Bug 605290: check for null globalObject before innerizing, r=luke
authorDavid Mandelin <dmandelin@mozilla.com>
Wed, 13 Jul 2011 16:47:10 -0700
changeset 72856 ecb74109d719ebd1ad27bb54b735f55685ee9097
parent 72855 0d25dd1013375e6019f9fd6649dc069415bc8a58
child 72857 e4a42cc36dc733793a6b6c2632b5e65c0528805f
push id20776
push usereakhgari@mozilla.com
push dateFri, 15 Jul 2011 12:13:35 +0000
treeherdermozilla-central@9349ae9094f6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersluke
bugs605290
milestone8.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 605290: check for null globalObject before innerizing, r=luke
js/src/jscntxtinlines.h
js/src/jscompartment.cpp
js/src/jsobj.cpp
js/src/jsobj.h
js/src/jsobjinlines.h
--- a/js/src/jscntxtinlines.h
+++ b/js/src/jscntxtinlines.h
@@ -64,21 +64,18 @@ GetGlobalForScopeChain(JSContext *cx)
      * trace or not, since we do not trace calls across global objects.
      */
     VOUCH_DOES_NOT_REQUIRE_STACK();
 
     if (cx->hasfp())
         return cx->fp()->scopeChain().getGlobal();
 
     JSObject *scope = cx->globalObject;
-    if (!scope) {
-        JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_INACTIVE);
+    if (!NULLABLE_OBJ_TO_INNER_OBJECT(cx, scope))
         return NULL;
-    }
-    OBJ_TO_INNER_OBJECT(cx, scope);
     return scope->asGlobal();
 }
 
 inline GSNCache *
 GetGSNCache(JSContext *cx)
 {
     return &JS_THREAD_DATA(cx)->gsnCache;
 }
--- a/js/src/jscompartment.cpp
+++ b/js/src/jscompartment.cpp
@@ -225,18 +225,17 @@ JSCompartment::wrap(JSContext *cx, Value
      * we parent all wrappers to the global object in their home compartment.
      * This loses us some transparency, and is generally very cheesy.
      */
     JSObject *global;
     if (cx->hasfp()) {
         global = cx->fp()->scopeChain().getGlobal();
     } else {
         global = cx->globalObject;
-        OBJ_TO_INNER_OBJECT(cx, global);
-        if (!global)
+        if (!NULLABLE_OBJ_TO_INNER_OBJECT(cx, global))
             return false;
     }
 
     /* Unwrap incoming objects. */
     if (vp->isObject()) {
         JSObject *obj = &vp->toObject();
 
         /* If the object is already in this compartment, we are done. */
--- a/js/src/jsobj.cpp
+++ b/js/src/jsobj.cpp
@@ -126,16 +126,27 @@ Class js_ObjectClass = {
 
 JS_FRIEND_API(JSObject *)
 js_ObjectToOuterObject(JSContext *cx, JSObject *obj)
 {
     OBJ_TO_OUTER_OBJECT(cx, obj);
     return obj;
 }
 
+JS_FRIEND_API(bool)
+NULLABLE_OBJ_TO_INNER_OBJECT(JSContext *cx, JSObject *&obj)
+{
+    if (!obj) {
+        JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_INACTIVE);
+        return false;
+    }
+    OBJ_TO_INNER_OBJECT(cx, obj);
+    return !!obj;
+}
+
 #if JS_HAS_OBJ_PROTO_PROP
 
 static JSBool
 obj_getProto(JSContext *cx, JSObject *obj, jsid id, Value *vp);
 
 static JSBool
 obj_setProto(JSContext *cx, JSObject *obj, jsid id, JSBool strict, Value *vp);
 
--- a/js/src/jsobj.h
+++ b/js/src/jsobj.h
@@ -1307,16 +1307,23 @@ struct JSObject_Slots16 : JSObject { js:
 
 inline void
 OBJ_TO_INNER_OBJECT(JSContext *cx, JSObject *&obj)
 {
     if (JSObjectOp op = obj->getClass()->ext.innerObject)
         obj = op(cx, obj);
 }
 
+/*
+ * It is safe to call with input obj == NULL. Return true iff output obj is
+ * non-NULL.
+ */
+extern JS_FRIEND_API(bool)
+NULLABLE_OBJ_TO_INNER_OBJECT(JSContext *cx, JSObject *&obj);
+
 inline void
 OBJ_TO_OUTER_OBJECT(JSContext *cx, JSObject *&obj)
 {
     if (JSObjectOp op = obj->getClass()->ext.outerObject)
         obj = op(cx, obj);
 }
 
 class JSValueArray {
--- a/js/src/jsobjinlines.h
+++ b/js/src/jsobjinlines.h
@@ -1097,18 +1097,17 @@ NewBuiltinClassInstance(JSContext *cx, C
 
     JSProtoKey protoKey = JSCLASS_CACHED_PROTO_KEY(clasp);
     JS_ASSERT(protoKey != JSProto_Null);
 
     /* NB: inline-expanded and specialized version of js_GetClassPrototype. */
     JSObject *global;
     if (!cx->hasfp()) {
         global = cx->globalObject;
-        OBJ_TO_INNER_OBJECT(cx, global);
-        if (!global)
+        if (!NULLABLE_OBJ_TO_INNER_OBJECT(cx, global))
             return NULL;
     } else {
         global = cx->fp()->scopeChain().getGlobal();
     }
     JS_ASSERT(global->isGlobal());
 
     const Value &v = global->getReservedSlot(JSProto_LIMIT + protoKey);
     JSObject *proto;