From 735b4b66f1e106a16ee3b50c6bb9b7d0b1369dda Mon Sep 17 00:00:00 2001 From: Jason Orendorff Date: Wed, 12 May 2010 09:34:03 -0500 Subject: [PATCH] Backed out changeset 8cb8888c68d3 due to failing mochitests. --- js/src/jsinterp.cpp | 62 +++++++++++-------- js/src/jsobj.cpp | 4 +- js/src/jsobj.h | 6 +- js/src/jspubtd.h | 16 +---- js/src/jstracer.cpp | 2 +- js/src/shell/js.cpp | 2 +- js/src/xpconnect/src/xpcJSWeakReference.cpp | 13 ++-- .../xpconnect/src/xpcwrappednativejsops.cpp | 11 +++- 8 files changed, 61 insertions(+), 55 deletions(-) diff --git a/js/src/jsinterp.cpp b/js/src/jsinterp.cpp index 6bf210b24e2..81193f36581 100644 --- a/js/src/jsinterp.cpp +++ b/js/src/jsinterp.cpp @@ -371,17 +371,11 @@ js_GetPrimitiveThis(JSContext *cx, jsval *vp, JSClass *clasp, jsval *thisvp) /* Some objects (e.g., With) delegate 'this' to another object. */ static inline JSObject * -CallThisObjectHook(JSContext *cx, JSObject *obj, JSObject *scope, jsval *argv) +CallThisObjectHook(JSContext *cx, JSObject *obj, jsval *argv) { - JSObject *thisp = obj; - if (JSThisObjectOp thisObject = obj->map->ops->thisObject) { - if (!scope) - scope = JSVAL_TO_OBJECT(argv[-2])->getGlobal(); - thisp = thisObject(cx, obj, scope); - if (!thisp) - return NULL; - } - + JSObject *thisp = obj->thisObject(cx); + if (!thisp) + return NULL; argv[-1] = OBJECT_TO_JSVAL(thisp); return thisp; } @@ -404,29 +398,45 @@ CallThisObjectHook(JSContext *cx, JSObject *obj, JSObject *scope, jsval *argv) JS_STATIC_INTERPRET JSObject * js_ComputeGlobalThis(JSContext *cx, jsval *argv) { - JSObject *thisp = JSVAL_TO_OBJECT(argv[-2])->getGlobal(); - return CallThisObjectHook(cx, thisp, thisp, argv); + JSObject *thisp; + + if (JSVAL_IS_PRIMITIVE(argv[-2]) || + !JSVAL_TO_OBJECT(argv[-2])->getParent()) { + thisp = cx->globalObject; + } else { + thisp = JSVAL_TO_OBJECT(argv[-2])->getGlobal(); + } + + return CallThisObjectHook(cx, thisp, argv); +} + +static JSObject * +ComputeThis(JSContext *cx, jsval *argv) +{ + JSObject *thisp; + + JS_ASSERT(!JSVAL_IS_NULL(argv[-1])); + if (!JSVAL_IS_OBJECT(argv[-1])) { + if (!js_PrimitiveToObject(cx, &argv[-1])) + return NULL; + thisp = JSVAL_TO_OBJECT(argv[-1]); + return thisp; + } + + thisp = JSVAL_TO_OBJECT(argv[-1]); + if (thisp->getClass() == &js_CallClass || thisp->getClass() == &js_BlockClass) + return js_ComputeGlobalThis(cx, argv); + + return CallThisObjectHook(cx, thisp, argv); } JSObject * js_ComputeThis(JSContext *cx, jsval *argv) { JS_ASSERT(argv[-1] != JSVAL_HOLE); // check for SynthesizeFrame poisoning - if (JSVAL_IS_NULL(argv[-1])) return js_ComputeGlobalThis(cx, argv); - - if (!JSVAL_IS_OBJECT(argv[-1])) { - if (!js_PrimitiveToObject(cx, &argv[-1])) - return NULL; - return JSVAL_TO_OBJECT(argv[-1]); - } - - JSObject *thisp = JSVAL_TO_OBJECT(argv[-1]); - if (thisp->getClass() == &js_CallClass || thisp->getClass() == &js_BlockClass) - return js_ComputeGlobalThis(cx, argv); - - return CallThisObjectHook(cx, thisp, NULL, argv); + return ComputeThis(cx, argv); } #if JS_HAS_NO_SUCH_METHOD @@ -1048,7 +1058,7 @@ js_Execute(JSContext *cx, JSObject *chain, JSScript *script, return false; frame.scopeChain = chain; - JSObject *thisp = JSVAL_TO_OBJECT(frame.thisv)->thisObject(cx, chain); + JSObject *thisp = JSVAL_TO_OBJECT(frame.thisv)->thisObject(cx); if (!thisp) return false; frame.thisv = OBJECT_TO_JSVAL(thisp); diff --git a/js/src/jsobj.cpp b/js/src/jsobj.cpp index 6cceede44c3..d42ffb82290 100644 --- a/js/src/jsobj.cpp +++ b/js/src/jsobj.cpp @@ -2947,12 +2947,12 @@ with_TypeOf(JSContext *cx, JSObject *obj) } static JSObject * -with_ThisObject(JSContext *cx, JSObject *obj, JSObject *scope) +with_ThisObject(JSContext *cx, JSObject *obj) { JSObject *proto = obj->getProto(); if (!proto) return obj; - return proto->thisObject(cx, scope); + return proto->thisObject(cx); } JS_FRIEND_DATA(JSObjectOps) js_WithObjectOps = { diff --git a/js/src/jsobj.h b/js/src/jsobj.h index b2e2f4ceedd..960aaa4ca7d 100644 --- a/js/src/jsobj.h +++ b/js/src/jsobj.h @@ -161,7 +161,7 @@ struct JSObjectOps { JSTraceOp trace; /* Optionally non-null members start here. */ - JSThisObjectOp thisObject; + JSObjectOp thisObject; JSPropertyRefOp dropProperty; JSNative call; JSNative construct; @@ -634,8 +634,8 @@ struct JSObject { } /* These four are time-optimized to avoid stub calls. */ - JSObject *thisObject(JSContext *cx, JSObject *scope) { - return map->ops->thisObject ? map->ops->thisObject(cx, this, scope) : this; + JSObject *thisObject(JSContext *cx) { + return map->ops->thisObject ? map->ops->thisObject(cx, this) : this; } void dropProperty(JSContext *cx, JSProperty *prop) { diff --git a/js/src/jspubtd.h b/js/src/jspubtd.h index ff797e5afe5..9171a22c2eb 100644 --- a/js/src/jspubtd.h +++ b/js/src/jspubtd.h @@ -423,19 +423,9 @@ typedef JSBool (* JSEqualityOp)(JSContext *cx, JSObject *obj, jsval v, JSBool *bp); /* - * The type of JSObjectOps::thisObject. Return a "stunt this" object for obj, - * having a parent chain that ends in scope; or NULL on error. - * - * The engine guarantees that obj->map->ops->thisObject == the callback - * and that cx, obj, and scope are non-null. - */ -typedef JSObject * -(* JSThisObjectOp)(JSContext *cx, JSObject *obj, JSObject *scope); - -/* - * A generic type for functions mapping an object to another object, or null if - * an error or exception was thrown on cx. Used by JSObjectOps.innerObject and - * outerObject at present. + * A generic type for functions mapping an object to another object, or null + * if an error or exception was thrown on cx. Used by JSObjectOps.thisObject + * at present. */ typedef JSObject * (* JSObjectOp)(JSContext *cx, JSObject *obj); diff --git a/js/src/jstracer.cpp b/js/src/jstracer.cpp index fd4d183d318..cdb0a88985b 100644 --- a/js/src/jstracer.cpp +++ b/js/src/jstracer.cpp @@ -9516,7 +9516,7 @@ TraceRecorder::getThis(LIns*& this_ins) this_ins = get(&thisv); - JSObject* wrappedGlobal = globalObj->thisObject(cx, globalObj); + JSObject* wrappedGlobal = globalObj->thisObject(cx); if (!wrappedGlobal) RETURN_ERROR("globalObj->thisObject hook threw in getThis"); diff --git a/js/src/shell/js.cpp b/js/src/shell/js.cpp index 0bd535e6028..49e71838494 100644 --- a/js/src/shell/js.cpp +++ b/js/src/shell/js.cpp @@ -2763,7 +2763,7 @@ split_outerObject(JSContext *cx, JSObject *obj) } static JSObject * -split_thisObject(JSContext *cx, JSObject *obj, JSObject */*scope*/) +split_thisObject(JSContext *cx, JSObject *obj) { OBJ_TO_OUTER_OBJECT(cx, obj); if (!obj) diff --git a/js/src/xpconnect/src/xpcJSWeakReference.cpp b/js/src/xpconnect/src/xpcJSWeakReference.cpp index fe5faad6d4b..82358ea2807 100644 --- a/js/src/xpconnect/src/xpcJSWeakReference.cpp +++ b/js/src/xpconnect/src/xpcJSWeakReference.cpp @@ -133,16 +133,13 @@ xpcJSWeakReference::Get() // nsXPConnect::GetWrapperForObject. But it takes a lot of // arguments! It turns out that the thisObject hook on XPConnect // objects does the right thing though, so... - if (obj->map->ops->thisObject) + + if (obj->map->ops->thisObject && + !(obj = obj->map->ops->thisObject(cx, obj))) { - JSObject *scope = JS_GetScopeChain(cx); - if (!scope) - return NS_ERROR_FAILURE; - scope = JS_GetGlobalForObject(cx, scope); - obj = obj->map->ops->thisObject(cx, obj, scope); - if (!obj) - return NS_ERROR_FAILURE; + return NS_ERROR_FAILURE; } + *retval = OBJECT_TO_JSVAL(obj); } } diff --git a/js/src/xpconnect/src/xpcwrappednativejsops.cpp b/js/src/xpconnect/src/xpcwrappednativejsops.cpp index e5846c6ea63..c628cded40b 100644 --- a/js/src/xpconnect/src/xpcwrappednativejsops.cpp +++ b/js/src/xpconnect/src/xpcwrappednativejsops.cpp @@ -1477,7 +1477,7 @@ private: } // namespace static JSObject* -XPC_WN_JSOp_ThisObject(JSContext *cx, JSObject *obj, JSObject *scope) +XPC_WN_JSOp_ThisObject(JSContext *cx, JSObject *obj) { // None of the wrappers we could potentially hand out are threadsafe so // just hand out the given object. @@ -1488,6 +1488,15 @@ XPC_WN_JSOp_ThisObject(JSContext *cx, JSObject *obj, JSObject *scope) if(!obj) return nsnull; + JSObject *scope = JS_GetScopeChain(cx); + if(!scope) + { + XPCThrower::Throw(NS_ERROR_FAILURE, cx); + return nsnull; + } + + scope = JS_GetGlobalForObject(cx, scope); + XPCPerThreadData *threadData = XPCPerThreadData::GetData(cx); if(!threadData) {