Bug 945360 - Fix some recent new rooting hazards in SpiderMonkey; r=sfink
authorTerrence Cole <terrence@mozilla.com>
Mon, 02 Dec 2013 11:11:07 -0800
changeset 174021 f8b57cbe128a54b3250d3aa37c2905cd0c0a2a4f
parent 173985 044c28763a8d3fe3871b1d6cfadf67a62343b326
child 174022 2f40cd447dc01e873012c0ec9bda9ea1c427695b
push id445
push userffxbld
push dateMon, 10 Mar 2014 22:05:19 +0000
treeherdermozilla-release@dc38b741b04e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssfink
bugs945360
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 945360 - Fix some recent new rooting hazards in SpiderMonkey; r=sfink
js/src/jsfriendapi.cpp
js/src/vm/Debugger.cpp
js/src/vm/GlobalObject.cpp
js/src/vm/GlobalObject.h
--- a/js/src/jsfriendapi.cpp
+++ b/js/src/jsfriendapi.cpp
@@ -559,17 +559,18 @@ js::GetObjectProto(JSContext *cx, JS::Ha
     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);
-    return scope->global().getOrCreateEval(cx, eval);
+    Rooted<GlobalObject *> global(cx, &scope->global());
+    return GlobalObject::getOrCreateEval(cx, global, eval);
 }
 
 JS_FRIEND_API(void)
 js::SetReservedSlotWithBarrier(JSObject *obj, size_t slot, const js::Value &value)
 {
     obj->setSlot(slot, value);
 }
 
--- a/js/src/vm/Debugger.cpp
+++ b/js/src/vm/Debugger.cpp
@@ -94,27 +94,27 @@ ReportMoreArgsNeeded(JSContext *cx, cons
     s[0] = '0' + (required - 1);
     s[1] = '\0';
     JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_MORE_ARGS_NEEDED,
                          name, s, required == 2 ? "" : "s");
     return false;
 }
 
 static inline bool
-EnsureFunctionHasScript(JSContext *cx, JSFunction *fun)
+EnsureFunctionHasScript(JSContext *cx, HandleFunction fun)
 {
     if (fun->isInterpretedLazy()) {
         AutoCompartment ac(cx, fun);
         return !!fun->getOrCreateScript(cx);
     }
     return true;
 }
 
 static inline JSScript *
-GetOrCreateFunctionScript(JSContext *cx, JSFunction *fun)
+GetOrCreateFunctionScript(JSContext *cx, HandleFunction fun)
 {
     MOZ_ASSERT(fun->isInterpreted());
     if (!EnsureFunctionHasScript(cx, fun))
         return nullptr;
     return fun->nonLazyScript();
 }
 
 #define REQUIRE_ARGC(name, n)                                                 \
@@ -702,18 +702,21 @@ Debugger::wrapEnvironment(JSContext *cx,
 bool
 Debugger::wrapDebuggeeValue(JSContext *cx, MutableHandleValue vp)
 {
     assertSameCompartment(cx, object.get());
 
     if (vp.isObject()) {
         RootedObject obj(cx, &vp.toObject());
 
-        if (obj->is<JSFunction>() && !EnsureFunctionHasScript(cx, &obj->as<JSFunction>()))
-            return false;
+        if (obj->is<JSFunction>()) {
+            RootedFunction fun(cx, &obj->as<JSFunction>());
+            if (!EnsureFunctionHasScript(cx, fun))
+                return false;
+        }
 
         DependentAddPtr<ObjectWeakMap> p(cx, objects, obj);
         if (p) {
             vp.setObject(*p->value);
         } else {
             /* Create a new Debugger.Object for obj. */
             JSObject *proto = &object->getReservedSlot(JSSLOT_DEBUG_OBJECT_PROTO).toObject();
             JSObject *dobj =
--- a/js/src/vm/GlobalObject.cpp
+++ b/js/src/vm/GlobalObject.cpp
@@ -448,22 +448,23 @@ GlobalObject::create(JSContext *cx, cons
     JSObject *res = RegExpStatics::create(cx, global);
     if (!res)
         return nullptr;
 
     global->initSlot(REGEXP_STATICS, ObjectValue(*res));
     return global;
 }
 
-bool
-GlobalObject::getOrCreateEval(JSContext *cx, MutableHandleObject eval)
+/* static */ bool
+GlobalObject::getOrCreateEval(JSContext *cx, Handle<GlobalObject*> global,
+                              MutableHandleObject eval)
 {
-    if (!getOrCreateObjectPrototype(cx))
+    if (!global->getOrCreateObjectPrototype(cx))
         return false;
-    eval.set(&getSlotRefForCompilation(EVAL).toObject());
+    eval.set(&global->getSlotRefForCompilation(EVAL).toObject());
     return true;
 }
 
 bool
 GlobalObject::valueIsEval(Value val)
 {
     HeapSlot &eval = getSlotRef(EVAL);
     return eval.isObject() && eval.get() == val;
--- a/js/src/vm/GlobalObject.h
+++ b/js/src/vm/GlobalObject.h
@@ -585,17 +585,18 @@ class GlobalObject : public JSObject
     }
 
     static bool isRuntimeCodeGenEnabled(JSContext *cx, Handle<GlobalObject*> global);
 
     // Warn about use of the deprecated watch/unwatch functions in the global
     // in which |obj| was created, if no prior warning was given.
     static bool warnOnceAboutWatch(JSContext *cx, HandleObject obj);
 
-    bool getOrCreateEval(JSContext *cx, MutableHandleObject eval);
+    static bool getOrCreateEval(JSContext *cx, Handle<GlobalObject*> global,
+                                MutableHandleObject eval);
 
     // Infallibly test whether the given value is the eval function for this global.
     bool valueIsEval(Value val);
 
     // Implemented in jsiter.cpp.
     static bool initIteratorClasses(JSContext *cx, Handle<GlobalObject*> global);
 
     // Implemented in builtin/MapObject.cpp.