Bug 933681 - Resolve canonical eval() onto Xrayed globals. r=jorendorff
authorBobby Holley <bobbyholley@gmail.com>
Fri, 22 Nov 2013 10:55:43 -0800
changeset 157165 176caf61a97545ce3c5637b59ba9989394db94a7
parent 157164 93cead0610da1b529992f85f177fc98f4097cd68
child 157166 061c63d261e51e8a5f2e2418c638494dc771b590
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 - Resolve canonical eval() onto Xrayed globals. r=jorendorff
js/src/jsfriendapi.cpp
js/src/jsfriendapi.h
js/xpconnect/src/XPCJSRuntime.cpp
js/xpconnect/src/xpcprivate.h
js/xpconnect/wrappers/XrayWrapper.cpp
--- a/js/src/jsfriendapi.cpp
+++ b/js/src/jsfriendapi.cpp
@@ -555,16 +555,26 @@ js::GetObjectProto(JSContext *cx, JS::Ha
 {
     if (IsProxy(obj))
         return JS_GetPrototype(cx, obj, proto);
 
     proto.set(reinterpret_cast<const shadow::Object*>(obj.get())->type->proto);
     return true;
 }
 
+JS_FRIEND_API(bool)
+js::GetOriginalEval(JSContext *cx, HandleObject scope, MutableHandleObject eval)
+{
+    assertSameCompartment(cx, scope);
+    if (!scope->global().getOrCreateObjectPrototype(cx))
+        return false;
+    eval.set(&scope->global().getOriginalEval().toObject());
+    return true;
+}
+
 JS_FRIEND_API(void)
 js::SetReservedSlotWithBarrier(JSObject *obj, size_t slot, const js::Value &value)
 {
     obj->setSlot(slot, value);
 }
 
 JS_FRIEND_API(bool)
 js::GetGeneric(JSContext *cx, JSObject *objArg, JSObject *receiverArg, jsid idArg,
--- a/js/src/jsfriendapi.h
+++ b/js/src/jsfriendapi.h
@@ -539,16 +539,20 @@ JS_FRIEND_API(const JS::Value &)
 GetFunctionNativeReserved(JSObject *fun, size_t which);
 
 JS_FRIEND_API(void)
 SetFunctionNativeReserved(JSObject *fun, size_t which, const JS::Value &val);
 
 JS_FRIEND_API(bool)
 GetObjectProto(JSContext *cx, JS::Handle<JSObject*> obj, JS::MutableHandle<JSObject*> proto);
 
+JS_FRIEND_API(bool)
+GetOriginalEval(JSContext *cx, JS::HandleObject scope,
+                JS::MutableHandleObject eval);
+
 inline void *
 GetObjectPrivate(JSObject *obj)
 {
     const shadow::Object *nobj = reinterpret_cast<const shadow::Object*>(obj);
     void **addr = reinterpret_cast<void**>(&nobj->fixedSlots()[nobj->numFixedSlots()]);
     return *addr;
 }
 
--- a/js/xpconnect/src/XPCJSRuntime.cpp
+++ b/js/xpconnect/src/XPCJSRuntime.cpp
@@ -70,16 +70,17 @@ const char* const XPCJSRuntime::mStrings
     "Object",               // IDX_OBJECT
     "Function",             // IDX_FUNCTION
     "prototype",            // IDX_PROTOTYPE
     "createInstance",       // IDX_CREATE_INSTANCE
     "item",                 // IDX_ITEM
     "__proto__",            // IDX_PROTO
     "__iterator__",         // IDX_ITERATOR
     "__exposedProps__",     // IDX_EXPOSEDPROPS
+    "eval",                 // IDX_EVAL
 };
 
 /***************************************************************************/
 
 struct CX_AND_XPCRT_Data
 {
     JSContext* cx;
     XPCJSRuntime* rt;
--- a/js/xpconnect/src/xpcprivate.h
+++ b/js/xpconnect/src/xpcprivate.h
@@ -647,16 +647,17 @@ public:
         IDX_OBJECT                  ,
         IDX_FUNCTION                ,
         IDX_PROTOTYPE               ,
         IDX_CREATE_INSTANCE         ,
         IDX_ITEM                    ,
         IDX_PROTO                   ,
         IDX_ITERATOR                ,
         IDX_EXPOSEDPROPS            ,
+        IDX_EVAL                    ,
         IDX_TOTAL_COUNT // just a count of the above
     };
 
     jsid GetStringID(unsigned index) const
     {
         MOZ_ASSERT(index < IDX_TOTAL_COUNT, "index out of range");
         return mStrIDs[index];
     }
--- a/js/xpconnect/wrappers/XrayWrapper.cpp
+++ b/js/xpconnect/wrappers/XrayWrapper.cpp
@@ -810,28 +810,34 @@ XrayTraits::resolveOwnProperty(JSContext
     bool found = false;
     if (expando) {
         JSAutoCompartment ac(cx, expando);
         if (!JS_GetPropertyDescriptorById(cx, expando, id, 0, desc))
             return false;
         found = !!desc.object();
     }
 
-    // Next, check for ES standard classes.
+    // Next, check for ES builtins.
     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;
+        } else if (id == GetRTIdByIndex(cx, XPCJSRuntime::IDX_EVAL)) {
+            RootedObject eval(cx);
+            if (!js::GetOriginalEval(cx, target, &eval))
+                return false;
+            desc.value().set(ObjectValue(*eval));
+            found = true;
         }
     }
 
     if (found) {
         if (!JS_WrapPropertyDescriptor(cx, desc))
             return false;
         // Pretend the property lives on the wrapper.
         desc.object().set(wrapper);