Bug 1071177 - Add support for well-known and registered symbols as CPOW jsids. r=billm,jorendorff
authorTom Schuster <evilpies@gmail.com>
Tue, 07 Oct 2014 11:29:03 +0200
changeset 209133 6e6f184e59285a2dcdf106c830e7ec0db2da6a97
parent 209132 765ab5eaab5b12281c1cbad4c8a0828e37c92ba7
child 209134 2279791b5c6e8d55675db58f38ccfcba7c568ca9
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
reviewersbillm, jorendorff
bugs1071177
milestone35.0a1
Bug 1071177 - Add support for well-known and registered symbols as CPOW jsids. r=billm,jorendorff
js/ipc/JavaScriptLogging.h
js/ipc/JavaScriptShared.cpp
js/ipc/JavaScriptShared.h
js/ipc/JavaScriptTypes.ipdlh
--- a/js/ipc/JavaScriptLogging.h
+++ b/js/ipc/JavaScriptLogging.h
@@ -187,16 +187,20 @@ class Logging
               out = "<JSIID>";
               break;
           }
         }
     }
 
     void format(const Identifier &id, nsCString &out) {
         switch (id.variant.type()) {
+          case JSIDVariant::TSymbolVariant: {
+              out = "<Symbol>";
+              break;
+          }
           case JSIDVariant::TnsString: {
               nsAutoCString tmp;
               format(id.variant.get_nsString(), tmp);
               out = nsPrintfCString("\"%s\"", tmp.get());
               break;
           }
           case JSIDVariant::Tint32_t: {
               out = nsPrintfCString("%d", id.variant.get_int32_t());
--- a/js/ipc/JavaScriptShared.cpp
+++ b/js/ipc/JavaScriptShared.cpp
@@ -362,36 +362,98 @@ JavaScriptShared::toJSIDVariant(JSContex
             return false;
         *to = autoStr;
         return true;
     }
     if (JSID_IS_INT(from)) {
         *to = JSID_TO_INT(from);
         return true;
     }
-    MOZ_CRASH("NYI");
+    if (JSID_IS_SYMBOL(from)) {
+        SymbolVariant symVar;
+        if (!toSymbolVariant(cx, JSID_TO_SYMBOL(from), &symVar))
+            return false;
+        *to = symVar;
+        return true;
+    }
+    MOZ_ASSERT(false);
     return false;
 }
 
 bool
 JavaScriptShared::fromJSIDVariant(JSContext *cx, const JSIDVariant &from, MutableHandleId to)
 {
     switch (from.type()) {
+      case JSIDVariant::TSymbolVariant: {
+        Symbol *sym = fromSymbolVariant(cx, from.get_SymbolVariant());
+        if (!sym)
+            return false;
+        to.set(SYMBOL_TO_JSID(sym));
+        return true;
+      }
+
       case JSIDVariant::TnsString:
         return convertGeckoStringToId(cx, from.get_nsString(), to);
 
       case JSIDVariant::Tint32_t:
         to.set(INT_TO_JSID(from.get_int32_t()));
         return true;
 
       default:
         return false;
     }
 }
 
+bool
+JavaScriptShared::toSymbolVariant(JSContext *cx, JS::Symbol *symArg, SymbolVariant *symVarp)
+{
+    RootedSymbol sym(cx, symArg);
+    MOZ_ASSERT(sym);
+
+    SymbolCode code = GetSymbolCode(sym);
+    if (static_cast<uint32_t>(code) < WellKnownSymbolLimit) {
+        *symVarp = WellKnownSymbol(static_cast<uint32_t>(code));
+        return true;
+    }
+    if (code == SymbolCode::InSymbolRegistry) {
+        nsAutoJSString autoStr;
+        if (!autoStr.init(cx, GetSymbolDescription(sym)))
+            return false;
+        *symVarp = RegisteredSymbol(autoStr);
+        return true;
+    }
+    MOZ_CRASH("unique symbols not yet implemented");
+    return false;
+}
+
+JS::Symbol *
+JavaScriptShared::fromSymbolVariant(JSContext *cx, SymbolVariant symVar)
+{
+    switch (symVar.type()) {
+      case SymbolVariant::TWellKnownSymbol: {
+        uint32_t which = symVar.get_WellKnownSymbol().which();
+        if (which < WellKnownSymbolLimit)
+            return GetWellKnownSymbol(cx, static_cast<SymbolCode>(which));
+        MOZ_ASSERT(false, "bad child data");
+        return nullptr;
+      }
+
+      case SymbolVariant::TRegisteredSymbol: {
+        nsString key = symVar.get_RegisteredSymbol().key();
+        RootedString str(cx, JS_NewUCStringCopyN(cx, key.get(), key.Length()));
+        if (!str)
+            return nullptr;
+        return GetSymbolFor(cx, str);
+      }
+
+      default:
+        return nullptr;
+    }
+}
+
 /* static */ void
 JavaScriptShared::ConvertID(const nsID &from, JSIID *to)
 {
     to->m0() = from.m0;
     to->m1() = from.m1;
     to->m2() = from.m2;
     to->m3_0() = from.m3[0];
     to->m3_1() = from.m3[1];
--- a/js/ipc/JavaScriptShared.h
+++ b/js/ipc/JavaScriptShared.h
@@ -156,16 +156,19 @@ class JavaScriptShared
 
   protected:
     bool toVariant(JSContext *cx, JS::HandleValue from, JSVariant *to);
     bool fromVariant(JSContext *cx, const JSVariant &from, JS::MutableHandleValue to);
 
     bool toJSIDVariant(JSContext *cx, JS::HandleId from, JSIDVariant *to);
     bool fromJSIDVariant(JSContext *cx, const JSIDVariant &from, JS::MutableHandleId to);
 
+    bool toSymbolVariant(JSContext *cx, JS::Symbol *sym, SymbolVariant *symVarp);
+    JS::Symbol *fromSymbolVariant(JSContext *cx, SymbolVariant symVar);
+
     bool fromDescriptor(JSContext *cx, JS::Handle<JSPropertyDescriptor> desc,
                         PPropertyDescriptor *out);
     bool toDescriptor(JSContext *cx, const PPropertyDescriptor &in,
                       JS::MutableHandle<JSPropertyDescriptor> out);
 
     bool convertIdToGeckoString(JSContext *cx, JS::HandleId id, nsString *to);
     bool convertGeckoStringToId(JSContext *cx, const nsString &from, JS::MutableHandleId id);
 
--- a/js/ipc/JavaScriptTypes.ipdlh
+++ b/js/ipc/JavaScriptTypes.ipdlh
@@ -38,32 +38,49 @@ struct RemoteObject
 };
 
 union ObjectVariant
 {
     LocalObject;
     RemoteObject;
 };
 
+struct WellKnownSymbol
+{
+    uint32_t which;
+};
+
+struct RegisteredSymbol
+{
+    nsString key;
+};
+
+union SymbolVariant
+{
+    WellKnownSymbol;
+    RegisteredSymbol;
+};
+
 struct UndefinedVariant {};
 struct NullVariant {};
 
 union JSVariant
 {
     UndefinedVariant;
     NullVariant;
     ObjectVariant;
     nsString;   /* StringValue(x) */
     double;     /* NumberValue(x) */
     bool;       /* BooleanValue(x) */
     JSIID;      /* XPC nsIID */
 };
 
 union JSIDVariant
 {
+    SymbolVariant;
     nsString;
     int32_t;
 };
 
 struct ReturnSuccess
 {
 };