Bug 1071177 - Add support for well-known and registered symbols as CPOW jsids. r=billm,jorendorff
--- 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
{
};