Bug 933681 - Add lookups for standard classes in XrayWrapper. r=jorendorff
authorBobby Holley <bobbyholley@gmail.com>
Fri, 22 Nov 2013 10:55:42 -0800
changeset 157164 93cead0610da1b529992f85f177fc98f4097cd68
parent 157163 98881f65a6656a258b6b8338120ffe47184b15df
child 157165 176caf61a97545ce3c5637b59ba9989394db94a7
push id25703
push userphilringnalda@gmail.com
push dateSat, 23 Nov 2013 16:19:02 +0000
treeherdermozilla-central@ad6589ed742c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjorendorff
bugs933681
milestone28.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 933681 - Add lookups for standard classes in XrayWrapper. r=jorendorff
dom/tests/mochitest/general/test_interfaces.html
js/xpconnect/wrappers/XrayWrapper.cpp
--- a/dom/tests/mochitest/general/test_interfaces.html
+++ b/dom/tests/mochitest/general/test_interfaces.html
@@ -31,27 +31,30 @@ var ecmaGlobals =
     "Boolean",
     "DataView",
     "Date",
     "Error",
     "EvalError",
     "Float32Array",
     "Float64Array",
     "Function",
-    "Infinity",
+    // NB: We haven't bothered to resolve constants like Infinity and NaN on
+    // Xrayed windows (which are seen from the XBL scope). We could support
+    // this if needed with some refactoring.
+    {name: "Infinity", xbl: false},
     "Int16Array",
     "Int32Array",
     "Int8Array",
     "InternalError",
     {name: "Intl", desktop: true},
     "Iterator",
     "JSON",
     "Map",
     "Math",
-    "NaN",
+    {name: "NaN", xbl: false},
     "Number",
     "Object",
     {name: "ParallelArray", nightly: true},
     "Proxy",
     "RangeError",
     "ReferenceError",
     "RegExp",
     "Set",
@@ -652,19 +655,17 @@ function createInterfaceMap(isXBLScope) 
                  (entry.pref && !prefs.getBoolPref(entry.pref))) {
         interfaceMap[entry.name] = false;
       } else {
         interfaceMap[entry.name] = shouldExpect;
       }
     }
   }
 
-  // Standard ECMAScript global objects are not defined on the XBL scope, but
-  // everything else exists everywhere.
-  addInterfaces(ecmaGlobals, !isXBLScope);
+  addInterfaces(ecmaGlobals, true);
   addInterfaces(interfaceNamesInGlobalScope, true);
 
   return interfaceMap;
 }
 
 function runTest(isXBLScope) {
   var interfaceMap = createInterfaceMap(isXBLScope);
   for (var name of Object.getOwnPropertyNames(window)) {
--- a/js/xpconnect/wrappers/XrayWrapper.cpp
+++ b/js/xpconnect/wrappers/XrayWrapper.cpp
@@ -802,22 +802,40 @@ XrayTraits::resolveOwnProperty(JSContext
                                MutableHandle<JSPropertyDescriptor> desc, unsigned flags)
 {
     desc.object().set(nullptr);
     RootedObject target(cx, getTargetObject(wrapper));
     RootedObject expando(cx, getExpandoObject(cx, target, wrapper));
 
     // Check for expando properties first. Note that the expando object lives
     // in the target compartment.
+    bool found = false;
     if (expando) {
         JSAutoCompartment ac(cx, expando);
         if (!JS_GetPropertyDescriptorById(cx, expando, id, 0, desc))
             return false;
+        found = !!desc.object();
     }
-    if (desc.object()) {
+
+    // Next, check for ES standard classes.
+    if (!found && JS_IsGlobalObject(target)) {
+        JSProtoKey key = JS_IdToProtoKey(cx, id);
+        JSAutoCompartment ac(cx, target);
+        if (key != JSProto_Null) {
+            MOZ_ASSERT(key < JSProto_LIMIT);
+            RootedObject constructor(cx);
+            if (!JS_GetClassObject(cx, target, key, constructor.address()))
+                return false;
+            MOZ_ASSERT(constructor);
+            desc.value().set(ObjectValue(*constructor));
+            found = true;
+        }
+    }
+
+    if (found) {
         if (!JS_WrapPropertyDescriptor(cx, desc))
             return false;
         // Pretend the property lives on the wrapper.
         desc.object().set(wrapper);
         return true;
     }
     return true;
 }