From 6344ccf0e8dd1c4b3ee819987ecd81f67c82bc67 Mon Sep 17 00:00:00 2001 From: Jan de Mooij Date: Tue, 17 Jun 2014 11:28:50 +0200 Subject: [PATCH] Bug 1025875 part 3 - Make CompareStrings and CompareAtoms work with Latin1 strings. r=njn --- js/src/jit-test/tests/latin1/compare.js | 20 ++++++++++++ js/src/jsstr.cpp | 42 ++++++++++++++++--------- js/src/jsstr.h | 7 +++-- 3 files changed, 52 insertions(+), 17 deletions(-) create mode 100644 js/src/jit-test/tests/latin1/compare.js diff --git a/js/src/jit-test/tests/latin1/compare.js b/js/src/jit-test/tests/latin1/compare.js new file mode 100644 index 000000000000..c0203d037508 --- /dev/null +++ b/js/src/jit-test/tests/latin1/compare.js @@ -0,0 +1,20 @@ +function test() { + var arr = [ + toLatin1("abc"), + toLatin1("abcd"), + toLatin1("123\u00ff") + ]; + for (var i = 0; i < arr.length; i++) { + for (var j = 0; j < arr.length; j++) { + var s1 = arr[i]; + var s2 = arr[j]; + var s1tb = "\u1200" + s1; + var s2tb = "\u1200" + s2; + assertEq(s1 < s2, s1tb < s2tb); + assertEq(s1 > s2, s1tb > s2tb); + assertEq(s1 <= s2, s1tb <= s2tb); + assertEq(s1 >= s2, s1tb >= s2tb); + } + } +} +test(); diff --git a/js/src/jsstr.cpp b/js/src/jsstr.cpp index f995aefef3c0..0132264969db 100644 --- a/js/src/jsstr.cpp +++ b/js/src/jsstr.cpp @@ -4521,8 +4521,28 @@ js::EqualStrings(JSLinearString *str1, JSLinearString *str2) return EqualChars(str1, str2); } -static bool -CompareStringsImpl(JSContext *cx, JSString *str1, JSString *str2, int32_t *result) +static int32_t +CompareStringsImpl(JSLinearString *str1, JSLinearString *str2) +{ + size_t len1 = str1->length(); + size_t len2 = str2->length(); + + AutoCheckCannotGC nogc; + if (str1->hasLatin1Chars()) { + const Latin1Char *chars1 = str1->latin1Chars(nogc); + return str2->hasLatin1Chars() + ? CompareChars(chars1, len1, str2->latin1Chars(nogc), len2) + : CompareChars(chars1, len1, str2->twoByteChars(nogc), len2); + } + + const jschar *chars1 = str1->twoByteChars(nogc); + return str2->hasLatin1Chars() + ? CompareChars(chars1, len1, str2->latin1Chars(nogc), len2) + : CompareChars(chars1, len1, str2->twoByteChars(nogc), len2); +} + +bool +js::CompareStrings(JSContext *cx, JSString *str1, JSString *str2, int32_t *result) { JS_ASSERT(str1); JS_ASSERT(str2); @@ -4532,28 +4552,22 @@ CompareStringsImpl(JSContext *cx, JSString *str1, JSString *str2, int32_t *resul return true; } - const jschar *s1 = str1->getChars(cx); - if (!s1) + JSLinearString *linear1 = str1->ensureLinear(cx); + if (!linear1) return false; - const jschar *s2 = str2->getChars(cx); - if (!s2) + JSLinearString *linear2 = str2->ensureLinear(cx); + if (!linear2) return false; - *result = CompareChars(s1, str1->length(), s2, str2->length()); + *result = CompareStringsImpl(linear1, linear2); return true; } -bool -js::CompareStrings(JSContext *cx, JSString *str1, JSString *str2, int32_t *result) -{ - return CompareStringsImpl(cx, str1, str2, result); -} - int32_t js::CompareAtoms(JSAtom *atom1, JSAtom *atom2) { - return CompareChars(atom1->chars(), atom1->length(), atom2->chars(), atom2->length()); + return CompareStringsImpl(atom1, atom2); } bool diff --git a/js/src/jsstr.h b/js/src/jsstr.h index b021daf20a9b..49e3d4d4f1e8 100644 --- a/js/src/jsstr.h +++ b/js/src/jsstr.h @@ -48,16 +48,17 @@ SkipSpace(const CharT *s, const CharT *end) // Return less than, equal to, or greater than zero depending on whether // s1 is less than, equal to, or greater than s2. +template inline int32_t -CompareChars(const jschar *s1, size_t l1, const jschar *s2, size_t l2) +CompareChars(const Char1 *s1, size_t len1, const Char2 *s2, size_t len2) { - size_t n = Min(l1, l2); + size_t n = Min(len1, len2); for (size_t i = 0; i < n; i++) { if (int32_t cmp = s1[i] - s2[i]) return cmp; } - return (int32_t)(l1 - l2); + return int32_t(len1 - len2); } } /* namespace js */