Bug 851895 - Expand the this-fixup hack to include Cu. r=mrbkap
authorBobby Holley <bobbyholley@gmail.com>
Thu, 21 Mar 2013 08:20:46 -0700
changeset 125822 1653ada4e2510d587ea005551848fec7f6a87e78
parent 125821 b2391af8fecb4f421536cf31f7494b5dc60996c9
child 125823 dc052939828763df406f53df40edf877238d468f
push id25109
push userryanvm@gmail.com
push dateThu, 21 Mar 2013 19:52:05 +0000
treeherdermozilla-inbound@a83cbe4e0576 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmrbkap
bugs851895
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 851895 - Expand the this-fixup hack to include Cu. r=mrbkap
js/xpconnect/src/XPCWrappedNativeJSOps.cpp
--- a/js/xpconnect/src/XPCWrappedNativeJSOps.cpp
+++ b/js/xpconnect/src/XPCWrappedNativeJSOps.cpp
@@ -1394,24 +1394,34 @@ XPCNativeScriptableShared::PopulateJSCla
 // a proper |this|. So, if it's quite clear that we're in this situation and
 // about to use a |this| argument that just won't work, fix things up.
 //
 // This hack is only useful for getters/setters if someone sets an XPCOM object
 // as the prototype for a vanilla JS object and expects the XPCOM attributes to
 // work on the derived object, which we really don't want to support. But we
 // handle it anyway, for now, to minimize regression risk on an already-risky
 // landing.
+//
+// This hack is mainly useful for the NoHelper JSClass. We also fix up
+// Components.utils because it implements nsIXPCScriptable (giving it a custom
+// JSClass) but not nsIClassInfo (which would put the methods on a prototype).
+
+#define IS_NOHELPER_CLASS(clasp) (clasp == &XPC_WN_NoHelper_JSClass.base)
+#define IS_CU_CLASS(clasp) (clasp->name[0] == 'n' && !strcmp(clasp->name, "nsXPCComponents_Utils"))
+
 MOZ_ALWAYS_INLINE JSObject*
 FixUpThisIfBroken(JSObject *obj, JSObject *funobj)
 {
-    if (MOZ_UNLIKELY(funobj &&
-        (js::GetObjectClass(js::GetObjectParent(funobj)) == &XPC_WN_NoHelper_JSClass.base) &&
-        (js::GetObjectClass(obj) != &XPC_WN_NoHelper_JSClass.base)))
-    {
-        return js::GetObjectParent(funobj);
+    if (funobj) {
+        js::Class *parentClass = js::GetObjectClass(js::GetObjectParent(funobj));
+        if (MOZ_UNLIKELY((IS_NOHELPER_CLASS(parentClass) || IS_CU_CLASS(parentClass)) &&
+                         (js::GetObjectClass(obj) != parentClass)))
+        {
+            return js::GetObjectParent(funobj);
+        }
     }
     return obj;
 }
 
 JSBool
 XPC_WN_CallMethod(JSContext *cx, unsigned argc, jsval *vp)
 {
     NS_ASSERTION(JS_TypeOfValue(cx, JS_CALLEE(cx, vp)) == JSTYPE_FUNCTION, "bad function");