зеркало из https://github.com/mozilla/pjs.git
Bug 513065 - Part 3, compute scope in the engine before calling the thisObject hook. r=mrbkap.
This commit is contained in:
Родитель
e723a3bdd7
Коммит
ab890a859e
|
@ -371,11 +371,17 @@ 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, jsval *argv)
|
||||
CallThisObjectHook(JSContext *cx, JSObject *obj, JSObject *scope, jsval *argv)
|
||||
{
|
||||
JSObject *thisp = obj->thisObject(cx);
|
||||
if (!thisp)
|
||||
return NULL;
|
||||
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;
|
||||
}
|
||||
|
||||
argv[-1] = OBJECT_TO_JSVAL(thisp);
|
||||
return thisp;
|
||||
}
|
||||
|
@ -398,45 +404,29 @@ CallThisObjectHook(JSContext *cx, JSObject *obj, jsval *argv)
|
|||
JS_STATIC_INTERPRET JSObject *
|
||||
js_ComputeGlobalThis(JSContext *cx, jsval *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 *thisp = JSVAL_TO_OBJECT(argv[-2])->getGlobal();
|
||||
return CallThisObjectHook(cx, thisp, 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);
|
||||
return ComputeThis(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);
|
||||
}
|
||||
|
||||
#if JS_HAS_NO_SUCH_METHOD
|
||||
|
@ -1058,7 +1048,7 @@ js_Execute(JSContext *cx, JSObject *chain, JSScript *script,
|
|||
return false;
|
||||
frame.scopeChain = chain;
|
||||
|
||||
JSObject *thisp = JSVAL_TO_OBJECT(frame.thisv)->thisObject(cx);
|
||||
JSObject *thisp = JSVAL_TO_OBJECT(frame.thisv)->thisObject(cx, chain);
|
||||
if (!thisp)
|
||||
return false;
|
||||
frame.thisv = OBJECT_TO_JSVAL(thisp);
|
||||
|
|
|
@ -2947,12 +2947,12 @@ with_TypeOf(JSContext *cx, JSObject *obj)
|
|||
}
|
||||
|
||||
static JSObject *
|
||||
with_ThisObject(JSContext *cx, JSObject *obj)
|
||||
with_ThisObject(JSContext *cx, JSObject *obj, JSObject *scope)
|
||||
{
|
||||
JSObject *proto = obj->getProto();
|
||||
if (!proto)
|
||||
return obj;
|
||||
return proto->thisObject(cx);
|
||||
return proto->thisObject(cx, scope);
|
||||
}
|
||||
|
||||
JS_FRIEND_DATA(JSObjectOps) js_WithObjectOps = {
|
||||
|
|
|
@ -161,7 +161,7 @@ struct JSObjectOps {
|
|||
JSTraceOp trace;
|
||||
|
||||
/* Optionally non-null members start here. */
|
||||
JSObjectOp thisObject;
|
||||
JSThisObjectOp 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) {
|
||||
return map->ops->thisObject ? map->ops->thisObject(cx, this) : this;
|
||||
JSObject *thisObject(JSContext *cx, JSObject *scope) {
|
||||
return map->ops->thisObject ? map->ops->thisObject(cx, this, scope) : this;
|
||||
}
|
||||
|
||||
void dropProperty(JSContext *cx, JSProperty *prop) {
|
||||
|
|
|
@ -423,9 +423,19 @@ typedef JSBool
|
|||
(* JSEqualityOp)(JSContext *cx, JSObject *obj, jsval v, JSBool *bp);
|
||||
|
||||
/*
|
||||
* 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.
|
||||
* 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.
|
||||
*/
|
||||
typedef JSObject *
|
||||
(* JSObjectOp)(JSContext *cx, JSObject *obj);
|
||||
|
|
|
@ -9516,7 +9516,7 @@ TraceRecorder::getThis(LIns*& this_ins)
|
|||
|
||||
this_ins = get(&thisv);
|
||||
|
||||
JSObject* wrappedGlobal = globalObj->thisObject(cx);
|
||||
JSObject* wrappedGlobal = globalObj->thisObject(cx, globalObj);
|
||||
if (!wrappedGlobal)
|
||||
RETURN_ERROR("globalObj->thisObject hook threw in getThis");
|
||||
|
||||
|
|
|
@ -2763,7 +2763,7 @@ split_outerObject(JSContext *cx, JSObject *obj)
|
|||
}
|
||||
|
||||
static JSObject *
|
||||
split_thisObject(JSContext *cx, JSObject *obj)
|
||||
split_thisObject(JSContext *cx, JSObject *obj, JSObject */*scope*/)
|
||||
{
|
||||
OBJ_TO_OUTER_OBJECT(cx, obj);
|
||||
if (!obj)
|
||||
|
|
|
@ -133,13 +133,16 @@ 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 &&
|
||||
!(obj = obj->map->ops->thisObject(cx, obj)))
|
||||
if (obj->map->ops->thisObject)
|
||||
{
|
||||
return NS_ERROR_FAILURE;
|
||||
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;
|
||||
}
|
||||
|
||||
*retval = OBJECT_TO_JSVAL(obj);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1477,7 +1477,7 @@ private:
|
|||
} // namespace
|
||||
|
||||
static JSObject*
|
||||
XPC_WN_JSOp_ThisObject(JSContext *cx, JSObject *obj)
|
||||
XPC_WN_JSOp_ThisObject(JSContext *cx, JSObject *obj, JSObject *scope)
|
||||
{
|
||||
// None of the wrappers we could potentially hand out are threadsafe so
|
||||
// just hand out the given object.
|
||||
|
@ -1488,15 +1488,6 @@ XPC_WN_JSOp_ThisObject(JSContext *cx, JSObject *obj)
|
|||
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)
|
||||
{
|
||||
|
|
Загрузка…
Ссылка в новой задаче