Bug 1289003 - Part 3: Add JS_NewStringCopyUTF8N and JS_NewStringCopyUTF8Z. r=jwalden
☠☠ backed out by e1942a9b8742 ☠ ☠
authorTooru Fujisawa <arai_a@mac.com>
Sat, 13 Aug 2016 23:24:22 +0900
changeset 312398 3abe6a1579f9bc79816ab781869b5232a1b3e483
parent 312397 1bbdfed5b149b231a27692542b6cee5b9f5138a8
child 312399 565bac97a123fa4d0e7e623a1df448085b3afec9
push id20447
push userkwierso@gmail.com
push dateFri, 02 Sep 2016 20:36:44 +0000
treeherderfx-team@969397f22187 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjwalden
bugs1289003
milestone51.0a1
Bug 1289003 - Part 3: Add JS_NewStringCopyUTF8N and JS_NewStringCopyUTF8Z. r=jwalden
js/src/jsapi.cpp
js/src/jsapi.h
js/src/vm/String.cpp
js/src/vm/String.h
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -76,16 +76,17 @@
 #include "vm/HelperThreads.h"
 #include "vm/Interpreter.h"
 #include "vm/RegExpStatics.h"
 #include "vm/Runtime.h"
 #include "vm/SavedStacks.h"
 #include "vm/SelfHosting.h"
 #include "vm/Shape.h"
 #include "vm/StopIterationObject.h"
+#include "vm/String.h"
 #include "vm/StringBuffer.h"
 #include "vm/Symbol.h"
 #include "vm/TypedArrayCommon.h"
 #include "vm/WrapperObject.h"
 #include "vm/Xdr.h"
 
 #include "jsatominlines.h"
 #include "jsfuninlines.h"
@@ -4933,16 +4934,32 @@ JS_NewStringCopyZ(JSContext* cx, const c
 {
     AssertHeapIsIdle(cx);
     CHECK_REQUEST(cx);
     if (!s)
         return cx->runtime()->emptyString;
     return NewStringCopyZ<CanGC>(cx, s);
 }
 
+JS_PUBLIC_API(JSString*)
+JS_NewStringCopyUTF8Z(JSContext* cx, const JS::ConstUTF8CharsZ s)
+{
+    AssertHeapIsIdle(cx);
+    CHECK_REQUEST(cx);
+    return NewStringCopyUTF8Z<CanGC>(cx, s);
+}
+
+JS_PUBLIC_API(JSString*)
+JS_NewStringCopyUTF8N(JSContext* cx, const JS::UTF8Chars s)
+{
+    AssertHeapIsIdle(cx);
+    CHECK_REQUEST(cx);
+    return NewStringCopyUTF8N<CanGC>(cx, s);
+}
+
 JS_PUBLIC_API(bool)
 JS_StringHasBeenPinned(JSContext* cx, JSString* str)
 {
     AssertHeapIsIdle(cx);
     CHECK_REQUEST(cx);
 
     if (!str->isAtom())
         return false;
--- a/js/src/jsapi.h
+++ b/js/src/jsapi.h
@@ -22,16 +22,17 @@
 #include <stddef.h>
 #include <stdint.h>
 #include <stdio.h>
 
 #include "jsalloc.h"
 #include "jspubtd.h"
 
 #include "js/CallArgs.h"
+#include "js/CharacterEncoding.h"
 #include "js/Class.h"
 #include "js/GCVector.h"
 #include "js/HashTable.h"
 #include "js/Id.h"
 #include "js/Principals.h"
 #include "js/Realm.h"
 #include "js/RootingAPI.h"
 #include "js/TracingAPI.h"
@@ -4611,16 +4612,22 @@ class MOZ_STACK_CLASS JS_PUBLIC_API(Auto
  */
 extern JS_PUBLIC_API(JSString*)
 JS_NewStringCopyN(JSContext* cx, const char* s, size_t n);
 
 extern JS_PUBLIC_API(JSString*)
 JS_NewStringCopyZ(JSContext* cx, const char* s);
 
 extern JS_PUBLIC_API(JSString*)
+JS_NewStringCopyUTF8Z(JSContext* cx, const JS::ConstUTF8CharsZ s);
+
+extern JS_PUBLIC_API(JSString*)
+JS_NewStringCopyUTF8N(JSContext* cx, const JS::UTF8Chars s);
+
+extern JS_PUBLIC_API(JSString*)
 JS_AtomizeAndPinJSString(JSContext* cx, JS::HandleString str);
 
 extern JS_PUBLIC_API(JSString*)
 JS_AtomizeStringN(JSContext* cx, const char* s, size_t length);
 
 extern JS_PUBLIC_API(JSString*)
 JS_AtomizeString(JSContext* cx, const char* s);
 
--- a/js/src/vm/String.cpp
+++ b/js/src/vm/String.cpp
@@ -1298,16 +1298,52 @@ template JSFlatString*
 NewStringCopyN<NoGC>(ExclusiveContext* cx, const char16_t* s, size_t n);
 
 template JSFlatString*
 NewStringCopyN<CanGC>(ExclusiveContext* cx, const Latin1Char* s, size_t n);
 
 template JSFlatString*
 NewStringCopyN<NoGC>(ExclusiveContext* cx, const Latin1Char* s, size_t n);
 
+
+template <js::AllowGC allowGC>
+JSFlatString*
+NewStringCopyUTF8N(JSContext* cx, const JS::UTF8Chars utf8)
+{
+    JS::SmallestEncoding encoding = JS::FindSmallestEncoding(utf8);
+    if (encoding == JS::SmallestEncoding::ASCII)
+        return NewStringCopyN<allowGC>(cx, utf8.start().get(), utf8.length());
+
+    size_t length;
+    if (encoding == JS::SmallestEncoding::Latin1) {
+        Latin1Char* latin1 = UTF8CharsToNewLatin1CharsZ(cx, utf8, &length).get();
+        if (!latin1)
+            return nullptr;
+
+        JSFlatString* result = NewString<allowGC>(cx, latin1, length);
+        if (!result)
+            js_free((void*)latin1);
+        return result;
+    }
+
+    MOZ_ASSERT(encoding == JS::SmallestEncoding::UTF16);
+
+    char16_t* utf16 = UTF8CharsToNewTwoByteCharsZ(cx, utf8, &length).get();
+    if (!utf16)
+        return nullptr;
+
+    JSFlatString* result = NewString<allowGC>(cx, utf16, length);
+    if (!result)
+        js_free((void*)utf16);
+    return result;
+}
+
+template JSFlatString*
+NewStringCopyUTF8N<CanGC>(JSContext* cx, const JS::UTF8Chars utf8);
+
 } /* namespace js */
 
 #ifdef DEBUG
 void
 JSExtensibleString::dumpRepresentation(FILE* fp, int indent) const
 {
     dumpRepresentationHeader(fp, indent, "JSExtensibleString");
     indent += 2;
--- a/js/src/vm/String.h
+++ b/js/src/vm/String.h
@@ -1205,16 +1205,27 @@ NewStringCopyZ(js::ExclusiveContext* cx,
 
 template <js::AllowGC allowGC>
 inline JSFlatString*
 NewStringCopyZ(js::ExclusiveContext* cx, const char* s)
 {
     return NewStringCopyN<allowGC>(cx, s, strlen(s));
 }
 
+template <js::AllowGC allowGC>
+extern JSFlatString*
+NewStringCopyUTF8N(JSContext* cx, const JS::UTF8Chars utf8);
+
+template <js::AllowGC allowGC>
+inline JSFlatString*
+NewStringCopyUTF8Z(JSContext* cx, const JS::ConstUTF8CharsZ utf8)
+{
+    return NewStringCopyUTF8N<allowGC>(cx, JS::UTF8Chars(utf8.c_str(), strlen(utf8.c_str())));
+}
+
 } /* namespace js */
 
 // Addon IDs are interned atoms which are never destroyed. This detail is
 // not exposed outside the API.
 class JSAddonId : public JSAtom
 {};
 
 MOZ_ALWAYS_INLINE bool