Bug 1019512 part 1 - Make trim/trimLeft/trimRight work with Latin1 strings. r=luke
authorJan de Mooij <jdemooij@mozilla.com>
Thu, 05 Jun 2014 12:01:54 +0200
changeset 206031 67308d682238681c424d9d62d50405be7ff048a4
parent 206030 2d9924eaa36c8b47bebb25d7932fa97773825c6f
child 206032 c3d4d93e55b3b959dd1a2ba3664c4c57ca53b7b9
push id3741
push userasasaki@mozilla.com
push dateMon, 21 Jul 2014 20:25:18 +0000
treeherdermozilla-beta@4d6f46f5af68 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersluke
bugs1019512
milestone32.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1019512 part 1 - Make trim/trimLeft/trimRight work with Latin1 strings. r=luke
js/src/jit-test/tests/latin1/trim.js
js/src/jsstr.cpp
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/latin1/trim.js
@@ -0,0 +1,27 @@
+function test() {
+    // Latin1
+    var s = toLatin1("  \r\t\n\u00A0foo 123\t \r\n\u00A0");
+
+    var res = s.trim();
+    assertEq(isLatin1(res), true);
+    assertEq(res, "foo 123");
+
+    res = s.trimLeft();
+    assertEq(isLatin1(res), true);
+    assertEq(res, "foo 123\t \r\n\u00A0");
+
+    res = s.trimRight();
+    assertEq(isLatin1(res), true);
+    assertEq(res, "  \r\t\n\u00A0foo 123");
+
+    res = toLatin1("foo 1234").trim();
+    assertEq(isLatin1(res), true);
+    assertEq(res, "foo 1234");
+
+    // TwoByte
+    s = "  \r\t\n\u00A0\u2000foo\u1200123\t \r\n\u00A0\u2009";
+    assertEq(s.trim(), "foo\u1200123");
+    assertEq(s.trimLeft(), "foo\u1200123\t \r\n\u00A0\u2009");
+    assertEq(s.trimRight(), "  \r\t\n\u00A0\u2000foo\u1200123");
+}
+test();
--- a/js/src/jsstr.cpp
+++ b/js/src/jsstr.cpp
@@ -1714,65 +1714,83 @@ str_endsWith(JSContext *cx, unsigned arg
     JSLinearString *text = str->ensureLinear(cx);
     if (!text)
         return false;
 
     args.rval().setBoolean(HasSubstringAt(text, searchStr, start));
     return true;
 }
 
-static bool
-js_TrimString(JSContext *cx, Value *vp, bool trimLeft, bool trimRight)
+template <typename CharT>
+static void
+TrimString(const CharT *chars, bool trimLeft, bool trimRight, size_t length,
+           size_t *pBegin, size_t *pEnd)
 {
-    CallReceiver call = CallReceiverFromVp(vp);
-    RootedString str(cx, ThisToStringForStringProto(cx, call));
-    if (!str)
-        return false;
-    size_t length = str->length();
-    const jschar *chars = str->getChars(cx);
-    if (!chars)
-        return false;
-
-    size_t begin = 0;
-    size_t end = length;
+    size_t begin = 0, end = length;
 
     if (trimLeft) {
         while (begin < length && unicode::IsSpace(chars[begin]))
             ++begin;
     }
 
     if (trimRight) {
         while (end > begin && unicode::IsSpace(chars[end - 1]))
             --end;
     }
 
+    *pBegin = begin;
+    *pEnd = end;
+}
+
+static bool
+TrimString(JSContext *cx, Value *vp, bool trimLeft, bool trimRight)
+{
+    CallReceiver call = CallReceiverFromVp(vp);
+    RootedString str(cx, ThisToStringForStringProto(cx, call));
+    if (!str)
+        return false;
+
+    JSLinearString *linear = str->ensureLinear(cx);
+    if (!linear)
+        return false;
+
+    size_t length = linear->length();
+    size_t begin, end;
+    if (linear->hasLatin1Chars()) {
+        AutoCheckCannotGC nogc;
+        TrimString(linear->latin1Chars(nogc), trimLeft, trimRight, length, &begin, &end);
+    } else {
+        AutoCheckCannotGC nogc;
+        TrimString(linear->twoByteChars(nogc), trimLeft, trimRight, length, &begin, &end);
+    }
+
     str = js_NewDependentString(cx, str, begin, end - begin);
     if (!str)
         return false;
 
     call.rval().setString(str);
     return true;
 }
 
 static bool
 str_trim(JSContext *cx, unsigned argc, Value *vp)
 {
-    return js_TrimString(cx, vp, true, true);
+    return TrimString(cx, vp, true, true);
 }
 
 static bool
 str_trimLeft(JSContext *cx, unsigned argc, Value *vp)
 {
-    return js_TrimString(cx, vp, true, false);
+    return TrimString(cx, vp, true, false);
 }
 
 static bool
 str_trimRight(JSContext *cx, unsigned argc, Value *vp)
 {
-    return js_TrimString(cx, vp, false, true);
+    return TrimString(cx, vp, false, true);
 }
 
 /*
  * Perl-inspired string functions.
  */
 
 namespace {