зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1105045 - Outerize the receiver passed to proxy hooks. r=efaust.
--HG-- extra : commitid : G8ZDWGn76fj extra : rebase_source : 36759c408e28660aa958a1683743d972f2b96986
This commit is contained in:
Родитель
90259502e7
Коммит
8016bfee38
|
@ -1004,7 +1004,8 @@ GetObjectClassName(JSContext* cx, HandleObject obj);
|
|||
*/
|
||||
|
||||
/*
|
||||
* If obj a WindowProxy, return its current inner Window. Otherwise return obj.
|
||||
* If obj is a WindowProxy, return its current inner Window. Otherwise return
|
||||
* obj. This function can't fail and never returns nullptr.
|
||||
*
|
||||
* GetInnerObject is called when we need a scope chain; you never want a
|
||||
* WindowProxy on a scope chain.
|
||||
|
@ -1027,6 +1028,7 @@ GetInnerObject(JSObject* obj)
|
|||
|
||||
/*
|
||||
* If obj is a Window object, return the WindowProxy. Otherwise return obj.
|
||||
* This function can't fail; it never sets an exception or returns nullptr.
|
||||
*
|
||||
* This must be called before passing an object to script, if the object might
|
||||
* be a Window. (But usually those cases involve scope objects, and for those,
|
||||
|
|
|
@ -260,8 +260,18 @@ Proxy::hasOwn(JSContext* cx, HandleObject proxy, HandleId id, bool* bp)
|
|||
return handler->hasOwn(cx, proxy, id, bp);
|
||||
}
|
||||
|
||||
static Value
|
||||
OuterizeValue(JSContext* cx, HandleValue v)
|
||||
{
|
||||
if (v.isObject()) {
|
||||
RootedObject obj(cx, &v.toObject());
|
||||
return ObjectValue(*GetOuterObject(cx, obj));
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
bool
|
||||
Proxy::get(JSContext* cx, HandleObject proxy, HandleObject receiver, HandleId id,
|
||||
Proxy::get(JSContext* cx, HandleObject proxy, HandleObject receiver_, HandleId id,
|
||||
MutableHandleValue vp)
|
||||
{
|
||||
JS_CHECK_RECURSION(cx, return false);
|
||||
|
@ -271,6 +281,10 @@ Proxy::get(JSContext* cx, HandleObject proxy, HandleObject receiver, HandleId id
|
|||
if (!policy.allowed())
|
||||
return policy.returnValue();
|
||||
|
||||
// Outerize the receiver. Proxy handlers shouldn't have to know about
|
||||
// the Window/WindowProxy distinction.
|
||||
RootedObject receiver(cx, GetOuterObject(cx, receiver_));
|
||||
|
||||
if (handler->hasPrototype()) {
|
||||
bool own;
|
||||
if (!handler->hasOwn(cx, proxy, id, &own))
|
||||
|
@ -308,7 +322,7 @@ Proxy::callProp(JSContext* cx, HandleObject proxy, HandleObject receiver, Handle
|
|||
}
|
||||
|
||||
bool
|
||||
Proxy::set(JSContext* cx, HandleObject proxy, HandleId id, HandleValue v, HandleValue receiver,
|
||||
Proxy::set(JSContext* cx, HandleObject proxy, HandleId id, HandleValue v, HandleValue receiver_,
|
||||
ObjectOpResult& result)
|
||||
{
|
||||
JS_CHECK_RECURSION(cx, return false);
|
||||
|
@ -320,6 +334,10 @@ Proxy::set(JSContext* cx, HandleObject proxy, HandleId id, HandleValue v, Handle
|
|||
return result.succeed();
|
||||
}
|
||||
|
||||
// Outerize the receiver. Proxy handlers shouldn't have to know about
|
||||
// the Window/WindowProxy distinction.
|
||||
RootedValue receiver(cx, OuterizeValue(cx, receiver_));
|
||||
|
||||
// Special case. See the comment on BaseProxyHandler::mHasPrototype.
|
||||
if (handler->hasPrototype())
|
||||
return handler->BaseProxyHandler::set(cx, proxy, id, v, receiver, result);
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
// The global object can be the receiver passed to the get and set traps of a Proxy.
|
||||
|
||||
var global = this;
|
||||
var proto = Object.getPrototypeOf(global);
|
||||
var gets = 0, sets = 0;
|
||||
Object.setPrototypeOf(global, new Proxy(proto, {
|
||||
has(t, id) {
|
||||
return id === "bareword" || Reflect.has(t, id);
|
||||
},
|
||||
get(t, id, r) {
|
||||
gets++;
|
||||
assertEq(r, global);
|
||||
return Reflect.get(t, id, r);
|
||||
},
|
||||
set(t, id, v, r) {
|
||||
sets++;
|
||||
assertEq(r, global);
|
||||
return Reflect.set(t, id, v, r);
|
||||
}
|
||||
}));
|
||||
|
||||
assertEq(bareword, undefined);
|
||||
assertEq(gets, 1);
|
||||
|
||||
bareword = 12;
|
||||
assertEq(sets, 1);
|
||||
assertEq(global.bareword, 12);
|
||||
|
||||
reportCompare(0, 0);
|
Загрузка…
Ссылка в новой задаче