зеркало из https://github.com/mozilla/gecko-dev.git
Bug 903391: Evaluate both arguments in String.prototype.lastIndexOf. r=till
This commit is contained in:
Родитель
2c4a554595
Коммит
8e53c5e480
|
@ -1700,26 +1700,31 @@ LastIndexOfImpl(const TextChar* text, size_t textLen, const PatChar* pat, size_t
|
|||
return -1;
|
||||
}
|
||||
|
||||
// ES2017 draft rev 6859bb9ccaea9c6ede81d71e5320e3833b92cb3e
|
||||
// 21.1.3.9 String.prototype.lastIndexOf ( searchString [ , position ] )
|
||||
bool
|
||||
js::str_lastIndexOf(JSContext* cx, unsigned argc, Value* vp)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
RootedString textstr(cx, ToStringForStringFunction(cx, args.thisv()));
|
||||
if (!textstr)
|
||||
|
||||
// Steps 1-2.
|
||||
RootedString str(cx, ToStringForStringFunction(cx, args.thisv()));
|
||||
if (!str)
|
||||
return false;
|
||||
|
||||
RootedLinearString pat(cx, ArgToRootedString(cx, args, 0));
|
||||
if (!pat)
|
||||
// Step 3.
|
||||
RootedLinearString searchStr(cx, ArgToRootedString(cx, args, 0));
|
||||
if (!searchStr)
|
||||
return false;
|
||||
|
||||
size_t textLen = textstr->length();
|
||||
size_t patLen = pat->length();
|
||||
int start = textLen - patLen; // Start searching here
|
||||
if (start < 0) {
|
||||
args.rval().setInt32(-1);
|
||||
return true;
|
||||
}
|
||||
// Step 6.
|
||||
size_t len = str->length();
|
||||
|
||||
// Step 8.
|
||||
size_t searchLen = searchStr->length();
|
||||
|
||||
// Steps 4-5, 7.
|
||||
int start = len - searchLen; // Start searching here
|
||||
if (args.hasDefined(1)) {
|
||||
if (args[1].isInt32()) {
|
||||
int i = args[1].toInt32();
|
||||
|
@ -1741,29 +1746,36 @@ js::str_lastIndexOf(JSContext* cx, unsigned argc, Value* vp)
|
|||
}
|
||||
}
|
||||
|
||||
if (patLen == 0) {
|
||||
args.rval().setInt32(start);
|
||||
if (searchLen > len) {
|
||||
args.rval().setInt32(-1);
|
||||
return true;
|
||||
}
|
||||
|
||||
JSLinearString* text = textstr->ensureLinear(cx);
|
||||
if (searchLen == 0) {
|
||||
args.rval().setInt32(start);
|
||||
return true;
|
||||
}
|
||||
MOZ_ASSERT(0 <= start && size_t(start) < len);
|
||||
|
||||
JSLinearString* text = str->ensureLinear(cx);
|
||||
if (!text)
|
||||
return false;
|
||||
|
||||
// Step 9.
|
||||
int32_t res;
|
||||
AutoCheckCannotGC nogc;
|
||||
if (text->hasLatin1Chars()) {
|
||||
const Latin1Char* textChars = text->latin1Chars(nogc);
|
||||
if (pat->hasLatin1Chars())
|
||||
res = LastIndexOfImpl(textChars, textLen, pat->latin1Chars(nogc), patLen, start);
|
||||
if (searchStr->hasLatin1Chars())
|
||||
res = LastIndexOfImpl(textChars, len, searchStr->latin1Chars(nogc), searchLen, start);
|
||||
else
|
||||
res = LastIndexOfImpl(textChars, textLen, pat->twoByteChars(nogc), patLen, start);
|
||||
res = LastIndexOfImpl(textChars, len, searchStr->twoByteChars(nogc), searchLen, start);
|
||||
} else {
|
||||
const char16_t* textChars = text->twoByteChars(nogc);
|
||||
if (pat->hasLatin1Chars())
|
||||
res = LastIndexOfImpl(textChars, textLen, pat->latin1Chars(nogc), patLen, start);
|
||||
if (searchStr->hasLatin1Chars())
|
||||
res = LastIndexOfImpl(textChars, len, searchStr->latin1Chars(nogc), searchLen, start);
|
||||
else
|
||||
res = LastIndexOfImpl(textChars, textLen, pat->twoByteChars(nogc), patLen, start);
|
||||
res = LastIndexOfImpl(textChars, len, searchStr->twoByteChars(nogc), searchLen, start);
|
||||
}
|
||||
|
||||
args.rval().setInt32(res);
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
var str = "a";
|
||||
var searchStr = "abc";
|
||||
|
||||
var position = new Object();
|
||||
var valueOfCalled = false;
|
||||
function positionValueOf() {
|
||||
assertEq(valueOfCalled, false);
|
||||
valueOfCalled = true;
|
||||
return 0;
|
||||
}
|
||||
position.valueOf = positionValueOf;
|
||||
|
||||
var result = str.lastIndexOf(searchStr, position);
|
||||
assertEq(result, -1);
|
||||
assertEq(valueOfCalled, true);
|
||||
|
||||
if (typeof reportCompare == "function")
|
||||
reportCompare(0, 0);
|
Загрузка…
Ссылка в новой задаче