Bug 868637 - Simplify DOM Bindings JSON parsing. r=bz
authorBobby Holley <bobbyholley@gmail.com>
Tue, 07 May 2013 14:18:03 -0700
changeset 131164 e2c5a5d03c491e122452a6b73f62c81c7c271658
parent 131163 0550d3d146cff508a8465c54dfd82204aa67579b
child 131165 883e35db4839399e0023cac094b3bc9604cca87c
push id27718
push userbobbyholley@gmail.com
push dateTue, 07 May 2013 21:18:35 +0000
treeherdermozilla-inbound@e2c5a5d03c49 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbz
bugs868637
milestone23.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 868637 - Simplify DOM Bindings JSON parsing. r=bz At this point we could really just hoist the JSAPI call, but it's just cumbersome enough with all the casts that I don't really want to stick it in the codegen.
dom/bindings/BindingDeclarations.h
dom/bindings/BindingUtils.cpp
dom/bindings/Codegen.py
--- a/dom/bindings/BindingDeclarations.h
+++ b/dom/bindings/BindingDeclarations.h
@@ -29,20 +29,18 @@ class nsWrapperCache;
 class nsGlobalWindow;
 
 namespace mozilla {
 namespace dom {
 
 struct MainThreadDictionaryBase
 {
 protected:
-  JSContext* ParseJSON(const nsAString& aJSON,
-                       Maybe<JSAutoRequest>& aAr,
-                       Maybe<JSAutoCompartment>& aAc,
-                       Maybe< JS::Rooted<JS::Value> >& aVal);
+  bool ParseJSON(JSContext *aCx, const nsAString& aJSON,
+                 JS::MutableHandle<JS::Value> aVal);
 };
 
 struct EnumEntry {
   const char* value;
   size_t length;
 };
 
 class MOZ_STACK_CLASS GlobalObject
--- a/dom/bindings/BindingUtils.cpp
+++ b/dom/bindings/BindingUtils.cpp
@@ -1306,36 +1306,27 @@ SetXrayExpandoChain(JSObject* obj, JSObj
     MOZ_ASSERT(js::GetProxyHandler(obj)->family() == ProxyFamily());
     js::SetProxyExtra(obj, JSPROXYSLOT_XRAY_EXPANDO, v);
   } else {
     MOZ_ASSERT(JS_IsNativeFunction(obj, Constructor));
     js::SetFunctionNativeReserved(obj, CONSTRUCTOR_XRAY_EXPANDO_SLOT, v);
   }
 }
 
-JSContext*
-MainThreadDictionaryBase::ParseJSON(const nsAString& aJSON,
-                                    Maybe<JSAutoRequest>& aAr,
-                                    Maybe<JSAutoCompartment>& aAc,
-                                    Maybe< JS::Rooted<JS::Value> >& aVal)
+bool
+MainThreadDictionaryBase::ParseJSON(JSContext *aCx,
+                                    const nsAString& aJSON,
+                                    JS::MutableHandle<JS::Value> aVal)
 {
-  AutoSafeJSContext cx;
-  JS::Rooted<JSObject*> global(cx, JS_GetGlobalObject(cx));
-  aAr.construct(static_cast<JSContext*>(cx));
-  aAc.construct(static_cast<JSContext*>(cx), global);
-  aVal.construct(static_cast<JSContext*>(cx), JS::UndefinedValue());
   if (aJSON.IsEmpty()) {
-    return cx;
+    return true;
   }
-  if (!JS_ParseJSON(cx,
-                    static_cast<const jschar*>(PromiseFlatString(aJSON).get()),
-                    aJSON.Length(), aVal.ref().address())) {
-    return nullptr;
-  }
-  return cx;
+  return JS_ParseJSON(aCx,
+                      static_cast<const jschar*>(PromiseFlatString(aJSON).get()),
+                      aJSON.Length(), aVal.address());
 }
 
 static JSString*
 ConcatJSString(JSContext* cx, const char* pre, JSString* str, const char* post)
 {
   if (!str) {
     return nullptr;
   }
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -7345,29 +7345,20 @@ class CGDictionary(CGThing):
         memberDecls = ["  %s %s;" %
                        (self.getMemberType(m),
                         self.makeMemberName(m[0].identifier.name))
                        for m in self.memberInfo]
 
         return (string.Template(
                 "struct ${selfName} ${inheritance}{\n"
                 "  ${selfName}() {}\n"
-                "  bool Init(JSContext* cx, JS::Handle<JS::Value> val);\n"
+                "  bool Init(JSContext* cx, JS::Handle<JS::Value> val);\n" +
+                ("  bool Init(const nsAString& aJSON);\n" if not self.workers else "") +
                 "  bool ToObject(JSContext* cx, JS::Handle<JSObject*> parentObject, JS::Value *vp) const;\n"
                 "\n" +
-                ("  bool Init(const nsAString& aJSON)\n"
-                 "  {\n"
-                 "    Maybe<JSAutoRequest> ar;\n"
-                 "    Maybe<JSAutoCompartment> ac;\n"
-                 "    Maybe< JS::Rooted<JS::Value> > json;\n"
-                 "    JSContext* cx = ParseJSON(aJSON, ar, ac, json);\n"
-                 "    NS_ENSURE_TRUE(cx, false);\n"
-                 "    return Init(cx, json.ref());\n"
-                 "  }\n" if not self.workers else "") +
-                "\n" +
                 "\n".join(memberDecls) + "\n"
                 "private:\n"
                 "  // Disallow copy-construction\n"
                 "  ${selfName}(const ${selfName}&) MOZ_DELETE;\n" +
                 # NOTE: jsids are per-runtime, so don't use them in workers
                 ("  static bool InitIds(JSContext* cx);\n"
                  "  static bool initedIds;\n" if self.needToInitIds else "") +
                 "\n".join("  static jsid " +
@@ -7449,16 +7440,27 @@ class CGDictionary(CGThing):
              "  bool isNull = val.isNullOrUndefined();\n" if len(memberInits) > 0 else "") +
             "  if (!IsConvertibleToDictionary(cx, val)) {\n"
             "    return ThrowErrorMessage(cx, MSG_NOT_DICTIONARY);\n"
             "  }\n"
             "\n"
             "${initMembers}\n"
             "  return true;\n"
             "}\n"
+            "\n" +
+            ("bool\n"
+             "${selfName}::Init(const nsAString& aJSON)\n"
+             "{\n"
+             "  AutoSafeJSContext cx;\n"
+             "  JSAutoRequest ar(cx);\n"
+             "  JS::Rooted<JS::Value> json(cx);\n"
+             "  bool ok = ParseJSON(cx, aJSON, &json);\n"
+             "  NS_ENSURE_TRUE(ok, false);\n"
+             "  return Init(cx, json);\n"
+             "}\n" if not self.workers else "") +
             "\n"
             "bool\n"
             "${selfName}::ToObject(JSContext* cx, JS::Handle<JSObject*> parentObject, JS::Value *vp) const\n"
             "{\n" +
             # NOTE: jsids are per-runtime, so don't use them in workers
             ("  if (!initedIds && !InitIds(cx)) {\n"
              "    return false;\n"
              "  }\n" if self.needToInitIds else "") +