Bug 832014 part 7. Fix Xray support for unforgeable methods. r=peterv
authorBoris Zbarsky <bzbarsky@mit.edu>
Fri, 11 Jul 2014 19:32:16 -0400
changeset 215629 460159ffbb79a924d5de2f00145a642f9b0c97ec
parent 215628 ddfd6eb4518f65bb3cb8d01d936158aebcc44371
child 215630 fb30689a1d8c665db1df49529b44656351efa7fc
push id515
push userraliiev@mozilla.com
push dateMon, 06 Oct 2014 12:51:51 +0000
treeherdermozilla-release@267c7a481bef [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerspeterv
bugs832014
milestone33.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 832014 part 7. Fix Xray support for unforgeable methods. r=peterv
dom/bindings/BindingUtils.cpp
--- a/dom/bindings/BindingUtils.cpp
+++ b/dom/bindings/BindingUtils.cpp
@@ -1056,28 +1056,101 @@ XrayResolveAttribute(JSContext* cx, JS::
           return true;
         }
       }
     }
   }
   return true;
 }
 
+static bool
+XrayResolveMethod(JSContext* cx, JS::Handle<JSObject*> wrapper,
+                  JS::Handle<JSObject*> obj, JS::Handle<jsid> id,
+                  const Prefable<const JSFunctionSpec>* methods,
+                  jsid* methodIds,
+                  const JSFunctionSpec* methodsSpecs,
+                  JS::MutableHandle<JSPropertyDescriptor> desc)
+{
+  const Prefable<const JSFunctionSpec>* method;
+  for (method = methods; method->specs; ++method) {
+    if (method->isEnabled(cx, obj)) {
+      // Set i to be the index into our full list of ids/specs that we're
+      // looking at now.
+      size_t i = method->specs - methodsSpecs;
+      for ( ; methodIds[i] != JSID_VOID; ++i) {
+        if (id == methodIds[i]) {
+          const JSFunctionSpec& methodSpec = methodsSpecs[i];
+          JSFunction *fun;
+          if (methodSpec.selfHostedName) {
+            fun = JS::GetSelfHostedFunction(cx, methodSpec.selfHostedName, id, methodSpec.nargs);
+            if (!fun) {
+              return false;
+            }
+            MOZ_ASSERT(!methodSpec.call.op, "Bad FunctionSpec declaration: non-null native");
+            MOZ_ASSERT(!methodSpec.call.info, "Bad FunctionSpec declaration: non-null jitinfo");
+          } else {
+            fun = JS_NewFunctionById(cx, methodSpec.call.op, methodSpec.nargs, 0, wrapper, id);
+            if (!fun) {
+              return false;
+            }
+            SET_JITINFO(fun, methodSpec.call.info);
+          }
+          JSObject *funobj = JS_GetFunctionObject(fun);
+          desc.value().setObject(*funobj);
+          desc.setAttributes(methodSpec.flags);
+          desc.object().set(wrapper);
+          desc.setSetter(nullptr);
+          desc.setGetter(nullptr);
+          return true;
+        }
+      }
+    }
+  }
+  return true;
+}
+
 /* static */ bool
 XrayResolveUnforgeableProperty(JSContext* cx, JS::Handle<JSObject*> wrapper,
                                JS::Handle<JSObject*> obj, JS::Handle<jsid> id,
                                JS::MutableHandle<JSPropertyDescriptor> desc,
                                const NativeProperties* nativeProperties)
 {
-  return !nativeProperties || !nativeProperties->unforgeableAttributes ||
-         XrayResolveAttribute(cx, wrapper, obj, id,
+  if (!nativeProperties) {
+    return true;
+  }
+
+  if (nativeProperties->unforgeableAttributes) {
+    if (!XrayResolveAttribute(cx, wrapper, obj, id,
                               nativeProperties->unforgeableAttributes,
                               nativeProperties->unforgeableAttributeIds,
                               nativeProperties->unforgeableAttributeSpecs,
-                              desc);
+                              desc)) {
+      return false;
+    }
+
+    if (desc.object()) {
+      return true;
+    }
+  }
+
+  if (nativeProperties->unforgeableMethods) {
+    if (!XrayResolveMethod(cx, wrapper, obj, id,
+                           nativeProperties->unforgeableMethods,
+                           nativeProperties->unforgeableMethodIds,
+                           nativeProperties->unforgeableMethodSpecs,
+                           desc)) {
+      return false;
+    }
+
+    if (desc.object()) {
+      return true;
+    }
+  }
+
+  return true;
 }
 
 static bool
 XrayResolveProperty(JSContext* cx, JS::Handle<JSObject*> wrapper,
                     JS::Handle<JSObject*> obj, JS::Handle<jsid> id,
                     JS::MutableHandle<JSPropertyDescriptor> desc, DOMObjectType type,
                     const NativeProperties* nativeProperties)
 {
@@ -1089,50 +1162,22 @@ XrayResolveProperty(JSContext* cx, JS::H
     methodIds = nativeProperties->staticMethodIds;
     methodsSpecs = nativeProperties->staticMethodsSpecs;
   } else {
     methods = nativeProperties->methods;
     methodIds = nativeProperties->methodIds;
     methodsSpecs = nativeProperties->methodsSpecs;
   }
   if (methods) {
-    const Prefable<const JSFunctionSpec>* method;
-    for (method = methods; method->specs; ++method) {
-      if (method->isEnabled(cx, obj)) {
-        // Set i to be the index into our full list of ids/specs that we're
-        // looking at now.
-        size_t i = method->specs - methodsSpecs;
-        for ( ; methodIds[i] != JSID_VOID; ++i) {
-          if (id == methodIds[i]) {
-            const JSFunctionSpec& methodSpec = methodsSpecs[i];
-            JSFunction *fun;
-            if (methodSpec.selfHostedName) {
-              fun = JS::GetSelfHostedFunction(cx, methodSpec.selfHostedName, id, methodSpec.nargs);
-              if (!fun) {
-                return false;
-              }
-              MOZ_ASSERT(!methodSpec.call.op, "Bad FunctionSpec declaration: non-null native");
-              MOZ_ASSERT(!methodSpec.call.info, "Bad FunctionSpec declaration: non-null jitinfo");
-            } else {
-              fun = JS_NewFunctionById(cx, methodSpec.call.op, methodSpec.nargs, 0, wrapper, id);
-              if (!fun) {
-                return false;
-              }
-              SET_JITINFO(fun, methodSpec.call.info);
-            }
-            JSObject *funobj = JS_GetFunctionObject(fun);
-            desc.value().setObject(*funobj);
-            desc.setAttributes(methodSpec.flags);
-            desc.object().set(wrapper);
-            desc.setSetter(nullptr);
-            desc.setGetter(nullptr);
-           return true;
-          }
-        }
-      }
+    if (!XrayResolveMethod(cx, wrapper, obj, id, methods, methodIds,
+                           methodsSpecs, desc)) {
+      return false;
+    }
+    if (desc.object()) {
+      return true;
     }
   }
 
   if (type == eInterface) {
     if (nativeProperties->staticAttributes) {
       if (!XrayResolveAttribute(cx, wrapper, obj, id,
                                 nativeProperties->staticAttributes,
                                 nativeProperties->staticAttributeIds,