diff --git a/js/src/builtin/String.cpp b/js/src/builtin/String.cpp index 83bb72716647..16e92b554c91 100644 --- a/js/src/builtin/String.cpp +++ b/js/src/builtin/String.cpp @@ -2652,10 +2652,14 @@ bool js::StringLastIndexOf(JSContext* cx, HandleString string, return true; } + MOZ_ASSERT(len >= searchLen); + size_t start = len - searchLen; + if (searchLen == 0) { - *result = 0; + *result = start; return true; } + MOZ_ASSERT(start < len); JSLinearString* text = string->ensureLinear(cx); if (!text) { @@ -2667,9 +2671,6 @@ bool js::StringLastIndexOf(JSContext* cx, HandleString string, return false; } - MOZ_ASSERT(len >= searchLen); - size_t start = len - searchLen; - *result = LastIndexOf(text, searchStr, start); return true; } diff --git a/js/src/jit-test/tests/cacheir/string-lastIndexOf.js b/js/src/jit-test/tests/cacheir/string-lastIndexOf.js new file mode 100644 index 000000000000..f281d1eac123 --- /dev/null +++ b/js/src/jit-test/tests/cacheir/string-lastIndexOf.js @@ -0,0 +1,102 @@ +function testEmpty() { + var strings = [ + "", + "a", + "ab", + ]; + + for (var i = 0; i < 200; ++i) { + var str = strings[i % strings.length]; + assertEq(str.lastIndexOf(""), str.length); + } +} +testEmpty(); + +function testSingle() { + var strings = [ + "", + + "a", + "b", + + "aa", + "ab", + "ba", + "bb", + ]; + + var searchStrings = [ + "a", + "b", + ]; + + for (var i = 0; i < 200; ++i) { + var str = strings[i % strings.length]; + var searchString = searchStrings[i % searchStrings.length]; + + var j = str.length; + while (--j >= 0 && str[j] !== searchString); + + assertEq(str.lastIndexOf(searchString), j); + } +} +testSingle(); + +function testDouble() { + var strings = [ + "", + + "a", + "b", + + "aa", + "ab", + "ba", + "bb", + + "aaa", + "aab", + "aba", + "abb", + "baa", + "bab", + "bba", + "bbb", + + "aaaa", + "aaab", + "aaba", + "aabb", + "abaa", + "abab", + "abba", + "abbb", + + "baaa", + "baab", + "baba", + "babb", + "bbaa", + "bbab", + "bbba", + "bbbb", + ]; + + var searchStrings = [ + "aa", + "ab", + "ba", + "bb", + ]; + + for (var i = 0; i < 200; ++i) { + var str = strings[i % strings.length]; + var searchString = searchStrings[i % searchStrings.length]; + + var j = str.length; + while (--j >= 0 && (str[j] !== searchString[0] || str[j + 1] !== searchString[1])); + + assertEq(str.lastIndexOf(searchString), j); + } +} +testDouble();