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 207115 67308d682238681c424d9d62d50405be7ff048a4
parent 207114 2d9924eaa36c8b47bebb25d7932fa97773825c6f
child 207116 c3d4d93e55b3b959dd1a2ba3664c4c57ca53b7b9
push id494
push userraliiev@mozilla.com
push dateMon, 25 Aug 2014 18:42:16 +0000
treeherdermozilla-release@a3cc3e46b571 [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 {