Bug 1271653 - Global environment functions should assert that referent is global;r=jimb
☠☠ backed out by 80bf1af3cd28 ☠ ☠
authorEddy Bruel <ejpbruel@mozilla.com>
Mon, 06 Jun 2016 18:26:29 +0200
changeset 325792 7a197b8bd00acc1e8baa6e9b9f93b2ee2809783e
parent 325791 5aa770304f2a519fda0989790b2d059d85a1db58
child 325793 0ae7b65e1c12135b5452b635608f311d5dac99d9
push id9858
push userjlund@mozilla.com
push dateMon, 01 Aug 2016 14:37:10 +0000
treeherdermozilla-aurora@203106ef6cb6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjimb
bugs1271653
milestone49.0a1
Bug 1271653 - Global environment functions should assert that referent is global;r=jimb
js/src/vm/Debugger.cpp
js/src/vm/Debugger.h
--- a/js/src/vm/Debugger.cpp
+++ b/js/src/vm/Debugger.cpp
@@ -8657,16 +8657,19 @@ DebuggerObject_asEnvironment(JSContext* 
 // altered, otherwise it is false.
 bool
 DebuggerObject_forceLexicalInitializationByName(JSContext *cx, unsigned argc, Value* vp)
 {
     THIS_DEBUGOBJECT(cx, argc, vp, "forceLexicalInitializationByName", args, object)
     if (!args.requireAtLeast(cx, "Debugger.Object.prototype.forceLexicalInitializationByName", 1))
         return false;
 
+    if (!DebuggerObject::requireGlobal(cx, object))
+        return false;
+
     RootedId id(cx);
     if (!ValueToIdentifier(cx, args[0], &id))
         return false;
 
     bool result;
     if (!DebuggerObject::forceLexicalInitializationByName(cx, object, id, result))
         return false;
 
@@ -8676,16 +8679,19 @@ DebuggerObject_forceLexicalInitializatio
 
 static bool
 DebuggerObject_executeInGlobal(JSContext* cx, unsigned argc, Value* vp)
 {
     THIS_DEBUGOBJECT(cx, argc, vp, "executeInGlobal", args, object);
     if (!args.requireAtLeast(cx, "Debugger.Object.prototype.executeInGlobal", 1))
         return false;
 
+    if (!DebuggerObject::requireGlobal(cx, object))
+        return false;
+
     AutoStableStringChars stableChars(cx);
     if (!ValueToStableChars(cx, "Debugger.Object.prototype.executeInGlobal", args[0],
                             stableChars))
     {
         return false;
     }
     mozilla::Range<const char16_t> chars = stableChars.twoByteRange();
 
@@ -8698,16 +8704,19 @@ DebuggerObject_executeInGlobal(JSContext
 
 static bool
 DebuggerObject_executeInGlobalWithBindings(JSContext* cx, unsigned argc, Value* vp)
 {
     THIS_DEBUGOBJECT(cx, argc, vp, "executeInGlobalWithBindings", args, object);
     if (!args.requireAtLeast(cx, "Debugger.Object.prototype.executeInGlobalWithBindings", 2))
         return false;
 
+    if (!DebuggerObject::requireGlobal(cx, object))
+        return false;
+
     AutoStableStringChars stableChars(cx);
     if (!ValueToStableChars(cx, "Debugger.Object.prototype.executeInGlobalWithBindings", args[0],
                             stableChars))
     {
         return false;
     }
     mozilla::Range<const char16_t> chars = stableChars.twoByteRange();
 
@@ -8867,16 +8876,24 @@ DebuggerObject::isDebuggeeFunction(JSCon
     RootedObject referent(cx, object->referent());
     Debugger* dbg = object->owner();
 
     return referent->is<JSFunction>() &&
            dbg->observesGlobal(&referent->as<JSFunction>().global());
 }
 
 /* static */ bool
+DebuggerObject::isGlobal(JSContext* cx, Handle<DebuggerObject*> object)
+{
+    RootedObject referent(cx, object->referent());
+
+    return referent->is<GlobalObject>();
+}
+
+/* static */ bool
 DebuggerObject::className(JSContext* cx, Handle<DebuggerObject*> object,
                           MutableHandleString result)
 {
     RootedObject referent(cx, object->referent());
 
     const char* className;
     {
         AutoCompartment ac(cx, referent);
@@ -9277,31 +9294,28 @@ DebuggerObject::call(JSContext* cx, Hand
 
     return dbg->receiveCompletionValue(ac, ok, result, result);
 }
 
 /* static */ bool
 DebuggerObject::forceLexicalInitializationByName(JSContext* cx, Handle<DebuggerObject*> object,
                                                  HandleId id, bool& result)
 {
-    if (!DebuggerObject::requireGlobalObject(cx, object))
-        return false;
-
     if (!JSID_IS_STRING(id)) {
         JS_ReportErrorNumber(cx, GetErrorMessage, nullptr,
                              JSMSG_NOT_EXPECTED_TYPE, "Debugger.Object.prototype.forceLexicalInitializationByName",
                              "string", InformalValueTypeName(IdToValue(id)));
         return false;
     }
 
-
-    RootedObject referent(cx, object->referent());
-
-    RootedObject globalLexical(cx, &referent->as<GlobalObject>().lexicalScope());
-
+    MOZ_ASSERT(isGlobal(cx, object));
+
+    Rooted<GlobalObject*> referent(cx, &object->referent()->as<GlobalObject>());
+
+    RootedObject globalLexical(cx, &referent->lexicalScope());
     RootedObject pobj(cx);
     RootedShape shape(cx);
     if (!LookupProperty(cx, globalLexical, id, &pobj, &shape))
         return false;
 
     result = false;
     if (shape) {
         Value v = globalLexical->as<NativeObject>().getSlot(shape->slot());
@@ -9314,24 +9328,22 @@ DebuggerObject::forceLexicalInitializati
     return true;
 }
 
 /* static */ bool
 DebuggerObject::executeInGlobal(JSContext* cx, Handle<DebuggerObject*> object,
                                 mozilla::Range<const char16_t> chars, HandleObject bindings,
                                 const EvalOptions& options, MutableHandleValue result)
 {
-    if (!DebuggerObject::requireGlobalObject(cx, object))
-        return false;
-
-    RootedObject referent(cx, object->referent());
+    MOZ_ASSERT(isGlobal(cx, object));
+
+    Rooted<GlobalObject*> referent(cx, &object->referent()->as<GlobalObject>());
     Debugger* dbg = object->owner();
 
-    RootedObject globalLexical(cx, &referent->as<GlobalObject>().lexicalScope());
-
+    RootedObject globalLexical(cx, &referent->lexicalScope());
     return DebuggerGenericEval(cx, chars, bindings, options, result, dbg, globalLexical,
                                nullptr);
 }
 
 /* static */ bool
 DebuggerObject::makeDebuggeeValue(JSContext* cx, Handle<DebuggerObject*> object,
                                   HandleValue value_, MutableHandleValue result)
 {
@@ -9402,21 +9414,21 @@ DebuggerObject::unwrap(JSContext* cx, Ha
     if (!dbg->wrapDebuggeeObject(cx, &unwrapped))
         return false;
 
     result.set(&unwrapped->as<DebuggerObject>());
     return true;
 }
 
 /* static */ bool
-DebuggerObject::requireGlobalObject(JSContext* cx, Handle<DebuggerObject*> object)
-{
-    RootedObject referent(cx, object->referent());
-
-    if (!referent->is<GlobalObject>()) {
+DebuggerObject::requireGlobal(JSContext* cx, Handle<DebuggerObject*> object)
+{
+    if (!DebuggerObject::isGlobal(cx, object)) {
+        RootedObject referent(cx, object->referent());
+
         const char* isWrapper = "";
         const char* isWindowProxy = "";
 
         /* Help the poor programmer by pointing out wrappers around globals... */
         if (referent->is<WrapperObject>()) {
             referent = js::UncheckedUnwrap(referent);
             isWrapper = "a wrapper around ";
         }
--- a/js/src/vm/Debugger.h
+++ b/js/src/vm/Debugger.h
@@ -1048,16 +1048,17 @@ class DebuggerObject : public NativeObje
     static const Class class_;
 
     static NativeObject* initClass(JSContext* cx, HandleObject obj, HandleObject debugCtor);
     static DebuggerObject* create(JSContext* cx, HandleObject proto, HandleObject obj,
                                   HandleNativeObject debugger);
 
     static bool isFunction(JSContext* cx, Handle<DebuggerObject*> object);
     static bool isDebuggeeFunction(JSContext* cx, Handle<DebuggerObject*> object);
+    static bool isGlobal(JSContext* cx, Handle<DebuggerObject*> object);
     static bool className(JSContext* cx, Handle<DebuggerObject*> object,
                           MutableHandleString result);
     static bool name(JSContext* cx, Handle<DebuggerObject*> object, MutableHandleString result);
     static bool displayName(JSContext* cx, Handle<DebuggerObject*> object,
                             MutableHandleString result);
     static bool isBoundFunction(JSContext* cx, Handle<DebuggerObject*> object);
     static bool boundTargetFunction(JSContext* cx, Handle<DebuggerObject*> object,
                                     MutableHandleObject result);
@@ -1096,31 +1097,31 @@ class DebuggerObject : public NativeObje
                                 const EvalOptions& options, MutableHandleValue result);
     static bool makeDebuggeeValue(JSContext* cx, Handle<DebuggerObject*> object,
                                   HandleValue value, MutableHandleValue result);
     static bool unsafeDereference(JSContext* cx, Handle<DebuggerObject*> object,
                                   MutableHandleObject result);
     static bool unwrap(JSContext* cx, Handle<DebuggerObject*> object,
                        MutableHandle<DebuggerObject*> result);
 
+    static bool requireGlobal(JSContext* cx, Handle<DebuggerObject*> object);
+
   private:
     enum {
         OWNER_SLOT
     };
 
     static const unsigned RESERVED_SLOTS = 1;
 
     static const JSPropertySpec properties_[];
 #ifdef SPIDERMONKEY_PROMISE
     static const JSPropertySpec promiseProperties_[];
 #endif // SPIDERMONKEY_PROMISE
     static const JSFunctionSpec methods_[];
 
-    static bool requireGlobalObject(JSContext* cx, Handle<DebuggerObject*> object);
-
     JSObject* referent() const {
         JSObject* obj = (JSObject*) getPrivate();
         MOZ_ASSERT(obj);
         return obj;
     }
 
     Debugger* owner() const;
 };