Bug 658909 - Stop doing all the crazy stuff in GetWrappedNativeOfJSObject. r=mrbkap
authorBobby Holley <bobbyholley@gmail.com>
Thu, 21 Mar 2013 08:20:43 -0700
changeset 125770 d51f3b83f042cbb9b4786faca046908f25d4712c
parent 125769 852aa6b442bdd576ecf7d44ac7aa4f8d939894b7
child 125771 7a146d4b5bd6a1529c7035e63a07907178d73ed8
push id24464
push useremorley@mozilla.com
push dateFri, 22 Mar 2013 14:00:12 +0000
treeherdermozilla-central@3825fdbcec62 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmrbkap
bugs658909
milestone22.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 658909 - Stop doing all the crazy stuff in GetWrappedNativeOfJSObject. r=mrbkap
js/xpconnect/src/XPCWrappedNative.cpp
--- a/js/xpconnect/src/XPCWrappedNative.cpp
+++ b/js/xpconnect/src/XPCWrappedNative.cpp
@@ -1764,123 +1764,37 @@ XPCWrappedNative::GetWrappedNativeOfJSOb
 {
     NS_PRECONDITION(obj, "bad param");
 
     // fubobj must be null if called without cx.
     NS_PRECONDITION(cx || !funobj, "bad param");
 
     // *pTeaorOff must be null if pTearOff is given
     NS_PRECONDITION(!pTearOff || !*pTearOff, "bad param");
-
-    JSObject* cur;
-
-    XPCWrappedNativeProto* proto = nullptr;
-    nsIClassInfo* protoClassInfo = nullptr;
-
-    // When an object is unwrapped (near the bottom of this function), we need
-    // to enter its compartment. Unfortunately, given the crazy usage of gotos,
-    // scoped JSAutoCompartments are pretty much impossible. So instead, we use
-    // a single Maybe<JSAutoCompartment>, and let anyone who wants to enter a
-    // compartment destroy and then reconstruct it.
-    Maybe<JSAutoCompartment> mac;
-    if (cx)
-        mac.construct(cx, obj);
-
-    // If we were passed a function object then we need to find the correct
-    // wrapper out of those that might be in the callee obj's proto chain.
-
-    if (funobj) {
-        JSObject* funObjParent = js::UnwrapObject(js::GetObjectParent(funobj));
-        funObjParent = JS_ObjectToInnerObject(cx, funObjParent);
-        NS_ASSERTION(funObjParent, "funobj has no parent");
-
-        js::Class* funObjParentClass = js::GetObjectClass(funObjParent);
-
-        if (IS_PROTO_CLASS(funObjParentClass)) {
-            NS_ASSERTION(js::GetObjectParent(funObjParent), "funobj's parent (proto) is global");
-            proto = (XPCWrappedNativeProto*) js::GetObjectPrivate(funObjParent);
-            if (proto)
-                protoClassInfo = proto->GetClassInfo();
-        } else if (IS_WRAPPER_CLASS(funObjParentClass)) {
-            cur = funObjParent;
-            goto return_wrapper;
-        } else if (IS_TEAROFF_CLASS(funObjParentClass)) {
-            NS_ASSERTION(js::GetObjectParent(funObjParent), "funobj's parent (tearoff) is global");
-            cur = funObjParent;
-            goto return_tearoff;
+    if (pobj2)
+        *pobj2 = nullptr;
+
+    obj = js::UnwrapObjectChecked(obj, /* stopAtOuter = */ false);
+    if (!obj)
+        return nullptr;
+    js::Class *clasp = js::GetObjectClass(obj);
+    if (IS_WRAPPER_CLASS(clasp)) {
+        if (IS_WN_WRAPPER_OBJECT(obj)) {
+            return (XPCWrappedNative*)js::GetObjectPrivate(obj);
         } else {
-            NS_ERROR("function object has parent of unknown class!");
+            MOZ_ASSERT(IS_SLIM_WRAPPER_OBJECT(obj));
+            if (pobj2)
+                *pobj2 = obj;
             return nullptr;
         }
-    }
-
-  restart:
-    if (cx) {
-        mac.destroy();
-        mac.construct(cx, obj);
+    } else if (IS_TEAROFF_CLASS(clasp)) {
+        if (pTearOff)
+            *pTearOff = (XPCWrappedNativeTearOff*)js::GetObjectPrivate(obj);
+        return (XPCWrappedNative*)js::GetObjectPrivate(js::GetObjectParent(obj));
     }
-    for (cur = obj; cur; ) {
-        // this is on two lines to make the compiler happy given the goto.
-        js::Class* clazz;
-        clazz = js::GetObjectClass(cur);
-
-        if (IS_WRAPPER_CLASS(clazz)) {
-return_wrapper:
-            JSBool isWN = IS_WN_WRAPPER_OBJECT(cur);
-            XPCWrappedNative* wrapper =
-                isWN ? (XPCWrappedNative*) js::GetObjectPrivate(cur) : nullptr;
-            if (proto) {
-                XPCWrappedNativeProto* wrapper_proto =
-                    isWN ? wrapper->GetProto() : GetSlimWrapperProto(cur);
-                if (proto != wrapper_proto &&
-                    (!protoClassInfo || !wrapper_proto ||
-                     protoClassInfo != wrapper_proto->GetClassInfo()))
-                    goto next;
-            }
-            if (pobj2)
-                *pobj2 = isWN ? nullptr : cur;
-            return wrapper;
-        }
-
-        if (IS_TEAROFF_CLASS(clazz)) {
-return_tearoff:
-            XPCWrappedNative* wrapper =
-                (XPCWrappedNative*) js::GetObjectPrivate(js::GetObjectParent(cur));
-            if (proto && proto != wrapper->GetProto() &&
-                (proto->GetScope() != wrapper->GetScope() ||
-                 !protoClassInfo || !wrapper->GetProto() ||
-                 protoClassInfo != wrapper->GetProto()->GetClassInfo()))
-                goto next;
-            if (pobj2)
-                *pobj2 = nullptr;
-            XPCWrappedNativeTearOff* to = (XPCWrappedNativeTearOff*) js::GetObjectPrivate(cur);
-            if (!to)
-                return nullptr;
-            if (pTearOff)
-                *pTearOff = to;
-            return wrapper;
-        }
-
-        // Unwrap any wrapper wrappers.
-        JSObject *unsafeObj;
-        unsafeObj = cx
-                  ? XPCWrapper::Unwrap(cx, cur, /* stopAtOuter = */ false)
-                  : js::UnwrapObject(cur, /* stopAtOuter = */ false);
-        if (unsafeObj) {
-            obj = unsafeObj;
-            goto restart;
-        }
-
-      next:
-        if (!js::GetObjectProto(cx, cur, &cur))
-            return nullptr;
-    }
-
-    if (pobj2)
-        *pobj2 = nullptr;
     return nullptr;
 }
 
 JSBool
 XPCWrappedNative::ExtendSet(XPCCallContext& ccx, XPCNativeInterface* aInterface)
 {
     // This is only called while locked (during XPCWrappedNative::FindTearOff).