Bug 1052139 - Reorder the preventExtensions trap just after the [[Prototype]]-access traps. r=code-motion

--HG--
extra : rebase_source : 18f69552bad6922c1b602cbf81d6961883e4d5b8
This commit is contained in:
Jeff Walden 2014-10-21 11:40:04 -07:00
Родитель 1d2a7aa6cd
Коммит b012538ad3
22 изменённых файлов: 339 добавлений и 330 удалений

Просмотреть файл

@ -20,13 +20,6 @@ public:
{
}
virtual bool
preventExtensions(JSContext* aCx, JS::Handle<JSObject*> aProxy,
bool *succeeded) const MOZ_OVERRIDE
{
*succeeded = false;
return true;
}
virtual bool
getOwnPropDescriptor(JSContext* aCx, JS::Handle<JSObject*> aProxy,
JS::Handle<jsid> aId,
bool /* unused */,
@ -43,6 +36,13 @@ public:
delete_(JSContext* aCx, JS::Handle<JSObject*> aProxy, JS::Handle<jsid> aId,
bool* aBp) const MOZ_OVERRIDE;
virtual bool
preventExtensions(JSContext* aCx, JS::Handle<JSObject*> aProxy,
bool *succeeded) const MOZ_OVERRIDE
{
*succeeded = false;
return true;
}
virtual bool
isExtensible(JSContext* aCx, JS::Handle<JSObject*> aProxy,
bool* aIsExtensible) const MOZ_OVERRIDE
{

Просмотреть файл

@ -620,11 +620,11 @@ public:
bool *bp) const MOZ_OVERRIDE;
virtual bool enumerate(JSContext *cx, JS::Handle<JSObject*> proxy,
JS::AutoIdVector &props) const MOZ_OVERRIDE;
virtual bool isExtensible(JSContext *cx, JS::Handle<JSObject*> proxy, bool *extensible)
const MOZ_OVERRIDE;
virtual bool preventExtensions(JSContext *cx,
JS::Handle<JSObject*> proxy,
bool *succeeded) const MOZ_OVERRIDE;
virtual bool isExtensible(JSContext *cx, JS::Handle<JSObject*> proxy, bool *extensible)
const MOZ_OVERRIDE;
virtual bool has(JSContext *cx, JS::Handle<JSObject*> proxy,
JS::Handle<jsid> id, bool *bp) const MOZ_OVERRIDE;
virtual bool get(JSContext *cx, JS::Handle<JSObject*> proxy,
@ -707,27 +707,6 @@ const js::Class OuterWindowProxyClass =
nsOuterWindowProxy::ObjectMoved
));
bool
nsOuterWindowProxy::isExtensible(JSContext *cx, JS::Handle<JSObject*> proxy,
bool *extensible) const
{
// If [[Extensible]] could be false, then navigating a window could navigate
// to a window that's [[Extensible]] after being at one that wasn't: an
// invariant violation. So always report true for this.
*extensible = true;
return true;
}
bool
nsOuterWindowProxy::preventExtensions(JSContext *cx,
JS::Handle<JSObject*> proxy,
bool *succeeded) const
{
// See above.
*succeeded = false;
return true;
}
const char *
nsOuterWindowProxy::className(JSContext *cx, JS::Handle<JSObject*> proxy) const
{
@ -865,6 +844,27 @@ nsOuterWindowProxy::enumerate(JSContext *cx, JS::Handle<JSObject*> proxy,
return js::AppendUnique(cx, props, innerProps);
}
bool
nsOuterWindowProxy::preventExtensions(JSContext *cx,
JS::Handle<JSObject*> proxy,
bool *succeeded) const
{
// If [[Extensible]] could be false, then navigating a window could navigate
// to a window that's [[Extensible]] after being at one that wasn't: an
// invariant violation. So never change a window's extensibility.
*succeeded = false;
return true;
}
bool
nsOuterWindowProxy::isExtensible(JSContext *cx, JS::Handle<JSObject*> proxy,
bool *extensible) const
{
// See above.
*extensible = true;
return true;
}
bool
nsOuterWindowProxy::has(JSContext *cx, JS::Handle<JSObject*> proxy,
JS::Handle<jsid> id, bool *bp) const

Просмотреть файл

@ -141,18 +141,18 @@ DOMProxyHandler::EnsureExpandoObject(JSContext* cx, JS::Handle<JSObject*> obj)
}
bool
DOMProxyHandler::isExtensible(JSContext *cx, JS::Handle<JSObject*> proxy, bool *extensible) const
DOMProxyHandler::preventExtensions(JSContext *cx, JS::Handle<JSObject*> proxy,
bool *succeeded) const
{
// always extensible per WebIDL
*extensible = true;
*succeeded = false;
return true;
}
bool
DOMProxyHandler::preventExtensions(JSContext *cx, JS::Handle<JSObject*> proxy,
bool *succeeded) const
DOMProxyHandler::isExtensible(JSContext *cx, JS::Handle<JSObject*> proxy, bool *extensible) const
{
*succeeded = false;
*extensible = true;
return true;
}

Просмотреть файл

@ -115,10 +115,10 @@ public:
const;
bool delete_(JSContext* cx, JS::Handle<JSObject*> proxy,
JS::Handle<jsid> id, bool* bp) const MOZ_OVERRIDE;
bool isExtensible(JSContext *cx, JS::Handle<JSObject*> proxy, bool *extensible)
const MOZ_OVERRIDE;
bool preventExtensions(JSContext *cx, JS::Handle<JSObject*> proxy,
bool *succeeded) const MOZ_OVERRIDE;
bool isExtensible(JSContext *cx, JS::Handle<JSObject*> proxy, bool *extensible)
const MOZ_OVERRIDE;
bool has(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id,
bool* bp) const MOZ_OVERRIDE;
bool set(JSContext *cx, JS::Handle<JSObject*> proxy, JS::Handle<JSObject*> receiver,

Просмотреть файл

@ -71,8 +71,8 @@ class CPOWProxyHandler : public BaseProxyHandler
AutoIdVector &props) const MOZ_OVERRIDE;
virtual bool delete_(JSContext *cx, HandleObject proxy, HandleId id, bool *bp) const MOZ_OVERRIDE;
virtual bool enumerate(JSContext *cx, HandleObject proxy, AutoIdVector &props) const MOZ_OVERRIDE;
virtual bool isExtensible(JSContext *cx, HandleObject proxy, bool *extensible) const MOZ_OVERRIDE;
virtual bool preventExtensions(JSContext *cx, HandleObject proxy, bool *succeeded) const MOZ_OVERRIDE;
virtual bool isExtensible(JSContext *cx, HandleObject proxy, bool *extensible) const MOZ_OVERRIDE;
virtual bool has(JSContext *cx, HandleObject proxy, HandleId id, bool *bp) const MOZ_OVERRIDE;
virtual bool get(JSContext *cx, HandleObject proxy, HandleObject receiver,
HandleId id, MutableHandleValue vp) const MOZ_OVERRIDE;
@ -112,26 +112,6 @@ const CPOWProxyHandler CPOWProxyHandler::singleton;
} \
return owner->call args;
bool
CPOWProxyHandler::preventExtensions(JSContext *cx, HandleObject proxy, bool *succeeded) const
{
FORWARD(preventExtensions, (cx, proxy, succeeded));
}
bool
WrapperOwner::preventExtensions(JSContext *cx, HandleObject proxy, bool *succeeded)
{
ObjectId objId = idOf(proxy);
ReturnStatus status;
if (!SendPreventExtensions(objId, &status, succeeded))
return ipcfail(cx);
LOG_STACK();
return ok(cx, status);
}
bool
CPOWProxyHandler::getPropertyDescriptor(JSContext *cx, HandleObject proxy, HandleId id,
MutableHandle<JSPropertyDescriptor> desc) const
@ -475,6 +455,26 @@ WrapperOwner::getOwnEnumerablePropertyKeys(JSContext *cx, HandleObject proxy, Au
return getPropertyKeys(cx, proxy, JSITER_OWNONLY, props);
}
bool
CPOWProxyHandler::preventExtensions(JSContext *cx, HandleObject proxy, bool *succeeded) const
{
FORWARD(preventExtensions, (cx, proxy, succeeded));
}
bool
WrapperOwner::preventExtensions(JSContext *cx, HandleObject proxy, bool *succeeded)
{
ObjectId objId = idOf(proxy);
ReturnStatus status;
if (!SendPreventExtensions(objId, &status, succeeded))
return ipcfail(cx);
LOG_STACK();
return ok(cx, status);
}
bool
CPOWProxyHandler::isExtensible(JSContext *cx, HandleObject proxy, bool *extensible) const
{

Просмотреть файл

@ -40,8 +40,8 @@ class WrapperOwner : public virtual JavaScriptShared
bool ownPropertyKeys(JSContext *cx, JS::HandleObject proxy, JS::AutoIdVector &props);
bool delete_(JSContext *cx, JS::HandleObject proxy, JS::HandleId id, bool *bp);
bool enumerate(JSContext *cx, JS::HandleObject proxy, JS::AutoIdVector &props);
bool isExtensible(JSContext *cx, JS::HandleObject proxy, bool *extensible);
bool preventExtensions(JSContext *cx, JS::HandleObject proxy, bool *succeeded);
bool isExtensible(JSContext *cx, JS::HandleObject proxy, bool *extensible);
bool has(JSContext *cx, JS::HandleObject proxy, JS::HandleId id, bool *bp);
bool get(JSContext *cx, JS::HandleObject proxy, JS::HandleObject receiver,
JS::HandleId id, JS::MutableHandleValue vp);

Просмотреть файл

@ -2794,6 +2794,13 @@ JS_DeepFreezeObject(JSContext *cx, JS::Handle<JSObject*> obj);
extern JS_PUBLIC_API(bool)
JS_FreezeObject(JSContext *cx, JS::Handle<JSObject*> obj);
/*
* Attempt to make |obj| non-extensible. If an error occurs while making the
* attempt, return false (with a pending exception set, depending upon the
* nature of the error). If no error occurs, return true with |*succeeded| set
* to indicate whether the attempt successfully set the [[Extensible]] property
* to false.
*/
extern JS_PUBLIC_API(bool)
JS_PreventExtensions(JSContext *cx, JS::HandleObject obj, bool *succeeded);

Просмотреть файл

@ -256,8 +256,6 @@ class JS_FRIEND_API(BaseProxyHandler)
AutoIdVector &props) const = 0;
virtual bool delete_(JSContext *cx, HandleObject proxy, HandleId id, bool *bp) const = 0;
virtual bool enumerate(JSContext *cx, HandleObject proxy, AutoIdVector &props) const = 0;
virtual bool isExtensible(JSContext *cx, HandleObject proxy, bool *extensible) const = 0;
virtual bool preventExtensions(JSContext *cx, HandleObject proxy, bool *succeeded) const = 0;
/*
* These methods are standard, but the engine does not normally call them.
@ -271,6 +269,9 @@ class JS_FRIEND_API(BaseProxyHandler)
/* Non-standard but conceptual kin to {g,s}etPrototypeOf, so lives here. */
virtual bool setImmutablePrototype(JSContext *cx, HandleObject proxy, bool *succeeded) const;
virtual bool preventExtensions(JSContext *cx, HandleObject proxy, bool *succeeded) const = 0;
virtual bool isExtensible(JSContext *cx, HandleObject proxy, bool *extensible) const = 0;
/*
* These standard internal methods are implemented, as a convenience, so
* that ProxyHandler subclasses don't have to provide every single method.
@ -368,14 +369,14 @@ class JS_PUBLIC_API(DirectProxyHandler) : public BaseProxyHandler
bool *bp) const MOZ_OVERRIDE;
virtual bool enumerate(JSContext *cx, HandleObject proxy,
AutoIdVector &props) const MOZ_OVERRIDE;
virtual bool isExtensible(JSContext *cx, HandleObject proxy, bool *extensible) const MOZ_OVERRIDE;
virtual bool preventExtensions(JSContext *cx, HandleObject proxy, bool *succeeded) const MOZ_OVERRIDE;
virtual bool getPrototypeOf(JSContext *cx, HandleObject proxy,
MutableHandleObject protop) const MOZ_OVERRIDE;
virtual bool setPrototypeOf(JSContext *cx, HandleObject proxy, HandleObject proto,
bool *bp) const MOZ_OVERRIDE;
virtual bool setImmutablePrototype(JSContext *cx, HandleObject proxy,
bool *succeeded) const MOZ_OVERRIDE;
virtual bool preventExtensions(JSContext *cx, HandleObject proxy, bool *succeeded) const MOZ_OVERRIDE;
virtual bool isExtensible(JSContext *cx, HandleObject proxy, bool *extensible) const MOZ_OVERRIDE;
virtual bool has(JSContext *cx, HandleObject proxy, HandleId id,
bool *bp) const MOZ_OVERRIDE;
virtual bool get(JSContext *cx, HandleObject proxy, HandleObject receiver,

Просмотреть файл

@ -122,14 +122,14 @@ class JS_FRIEND_API(CrossCompartmentWrapper) : public Wrapper
AutoIdVector &props) const MOZ_OVERRIDE;
virtual bool delete_(JSContext *cx, HandleObject wrapper, HandleId id, bool *bp) const MOZ_OVERRIDE;
virtual bool enumerate(JSContext *cx, HandleObject wrapper, AutoIdVector &props) const MOZ_OVERRIDE;
virtual bool isExtensible(JSContext *cx, HandleObject wrapper, bool *extensible) const MOZ_OVERRIDE;
virtual bool preventExtensions(JSContext *cx, HandleObject wrapper, bool *succeeded) const MOZ_OVERRIDE;
virtual bool getPrototypeOf(JSContext *cx, HandleObject proxy,
MutableHandleObject protop) const MOZ_OVERRIDE;
virtual bool setPrototypeOf(JSContext *cx, HandleObject proxy, HandleObject proto,
bool *bp) const MOZ_OVERRIDE;
virtual bool setImmutablePrototype(JSContext *cx, HandleObject proxy,
bool *succeeded) const MOZ_OVERRIDE;
virtual bool preventExtensions(JSContext *cx, HandleObject wrapper, bool *succeeded) const MOZ_OVERRIDE;
virtual bool isExtensible(JSContext *cx, HandleObject wrapper, bool *extensible) const MOZ_OVERRIDE;
virtual bool has(JSContext *cx, HandleObject wrapper, HandleId id, bool *bp) const MOZ_OVERRIDE;
virtual bool get(JSContext *cx, HandleObject wrapper, HandleObject receiver,
HandleId id, MutableHandleValue vp) const MOZ_OVERRIDE;

Просмотреть файл

@ -27,25 +27,6 @@ using namespace js;
#define NOTHING (true)
bool
CrossCompartmentWrapper::isExtensible(JSContext *cx, HandleObject wrapper, bool *extensible) const
{
PIERCE(cx, wrapper,
NOTHING,
Wrapper::isExtensible(cx, wrapper, extensible),
NOTHING);
}
bool
CrossCompartmentWrapper::preventExtensions(JSContext *cx, HandleObject wrapper,
bool *succeeded) const
{
PIERCE(cx, wrapper,
NOTHING,
Wrapper::preventExtensions(cx, wrapper, succeeded),
NOTHING);
}
bool
CrossCompartmentWrapper::getPropertyDescriptor(JSContext *cx, HandleObject wrapper, HandleId id,
MutableHandle<PropertyDescriptor> desc) const
@ -105,6 +86,61 @@ CrossCompartmentWrapper::enumerate(JSContext *cx, HandleObject wrapper, AutoIdVe
NOTHING);
}
bool
CrossCompartmentWrapper::getPrototypeOf(JSContext *cx, HandleObject wrapper,
MutableHandleObject protop) const
{
{
RootedObject wrapped(cx, wrappedObject(wrapper));
AutoCompartment call(cx, wrapped);
if (!JSObject::getProto(cx, wrapped, protop))
return false;
if (protop)
protop->setDelegate(cx);
}
return cx->compartment()->wrap(cx, protop);
}
bool
CrossCompartmentWrapper::setPrototypeOf(JSContext *cx, HandleObject wrapper,
HandleObject proto, bool *bp) const
{
RootedObject protoCopy(cx, proto);
PIERCE(cx, wrapper,
cx->compartment()->wrap(cx, &protoCopy),
Wrapper::setPrototypeOf(cx, wrapper, protoCopy, bp),
NOTHING);
}
bool
CrossCompartmentWrapper::setImmutablePrototype(JSContext *cx, HandleObject wrapper, bool *succeeded) const
{
PIERCE(cx, wrapper,
NOTHING,
Wrapper::setImmutablePrototype(cx, wrapper, succeeded),
NOTHING);
}
bool
CrossCompartmentWrapper::preventExtensions(JSContext *cx, HandleObject wrapper,
bool *succeeded) const
{
PIERCE(cx, wrapper,
NOTHING,
Wrapper::preventExtensions(cx, wrapper, succeeded),
NOTHING);
}
bool
CrossCompartmentWrapper::isExtensible(JSContext *cx, HandleObject wrapper, bool *extensible) const
{
PIERCE(cx, wrapper,
NOTHING,
Wrapper::isExtensible(cx, wrapper, extensible),
NOTHING);
}
bool
CrossCompartmentWrapper::has(JSContext *cx, HandleObject wrapper, HandleId id, bool *bp) const
{
@ -405,42 +441,6 @@ CrossCompartmentWrapper::defaultValue(JSContext *cx, HandleObject wrapper, JSTyp
cx->compartment()->wrap(cx, vp));
}
bool
CrossCompartmentWrapper::getPrototypeOf(JSContext *cx, HandleObject wrapper,
MutableHandleObject protop) const
{
{
RootedObject wrapped(cx, wrappedObject(wrapper));
AutoCompartment call(cx, wrapped);
if (!JSObject::getProto(cx, wrapped, protop))
return false;
if (protop)
protop->setDelegate(cx);
}
return cx->compartment()->wrap(cx, protop);
}
bool
CrossCompartmentWrapper::setPrototypeOf(JSContext *cx, HandleObject wrapper,
HandleObject proto, bool *bp) const
{
RootedObject protoCopy(cx, proto);
PIERCE(cx, wrapper,
cx->compartment()->wrap(cx, &protoCopy),
Wrapper::setPrototypeOf(cx, wrapper, protoCopy, bp),
NOTHING);
}
bool
CrossCompartmentWrapper::setImmutablePrototype(JSContext *cx, HandleObject wrapper, bool *succeeded) const
{
PIERCE(cx, wrapper,
NOTHING,
Wrapper::setImmutablePrototype(cx, wrapper, succeeded),
NOTHING);
}
const CrossCompartmentWrapper CrossCompartmentWrapper::singleton(0u);
bool

Просмотреть файл

@ -14,22 +14,6 @@
using namespace js;
using namespace js::gc;
bool
DeadObjectProxy::isExtensible(JSContext *cx, HandleObject proxy, bool *extensible) const
{
// This is kind of meaningless, but dead-object semantics aside,
// [[Extensible]] always being true is consistent with other proxy types.
*extensible = true;
return true;
}
bool
DeadObjectProxy::preventExtensions(JSContext *cx, HandleObject proxy, bool *succeeded) const
{
JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_DEAD_OBJECT);
return false;
}
bool
DeadObjectProxy::getPropertyDescriptor(JSContext *cx, HandleObject wrapper, HandleId id,
MutableHandle<PropertyDescriptor> desc) const
@ -76,6 +60,29 @@ DeadObjectProxy::enumerate(JSContext *cx, HandleObject wrapper, AutoIdVector &pr
return false;
}
bool
DeadObjectProxy::getPrototypeOf(JSContext *cx, HandleObject proxy, MutableHandleObject protop) const
{
protop.set(nullptr);
return true;
}
bool
DeadObjectProxy::preventExtensions(JSContext *cx, HandleObject proxy, bool *succeeded) const
{
JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_DEAD_OBJECT);
return false;
}
bool
DeadObjectProxy::isExtensible(JSContext *cx, HandleObject proxy, bool *extensible) const
{
// This is kind of meaningless, but dead-object semantics aside,
// [[Extensible]] always being true is consistent with other proxy types.
*extensible = true;
return true;
}
bool
DeadObjectProxy::call(JSContext *cx, HandleObject wrapper, const CallArgs &args) const
{
@ -140,13 +147,6 @@ DeadObjectProxy::defaultValue(JSContext *cx, HandleObject obj, JSType hint,
return false;
}
bool
DeadObjectProxy::getPrototypeOf(JSContext *cx, HandleObject proxy, MutableHandleObject protop) const
{
protop.set(nullptr);
return true;
}
const char DeadObjectProxy::family = 0;
const DeadObjectProxy DeadObjectProxy::singleton;

Просмотреть файл

@ -27,10 +27,10 @@ class DeadObjectProxy : public BaseProxyHandler
AutoIdVector &props) const MOZ_OVERRIDE;
virtual bool delete_(JSContext *cx, HandleObject wrapper, HandleId id, bool *bp) const MOZ_OVERRIDE;
virtual bool enumerate(JSContext *cx, HandleObject wrapper, AutoIdVector &props) const MOZ_OVERRIDE;
virtual bool isExtensible(JSContext *cx, HandleObject proxy, bool *extensible) const MOZ_OVERRIDE;
virtual bool preventExtensions(JSContext *cx, HandleObject proxy, bool *succeeded) const MOZ_OVERRIDE;
virtual bool getPrototypeOf(JSContext *cx, HandleObject proxy,
MutableHandleObject protop) const MOZ_OVERRIDE;
virtual bool preventExtensions(JSContext *cx, HandleObject proxy, bool *succeeded) const MOZ_OVERRIDE;
virtual bool isExtensible(JSContext *cx, HandleObject proxy, bool *extensible) const MOZ_OVERRIDE;
virtual bool call(JSContext *cx, HandleObject proxy, const CallArgs &args) const MOZ_OVERRIDE;
virtual bool construct(JSContext *cx, HandleObject proxy, const CallArgs &args) const MOZ_OVERRIDE;

Просмотреть файл

@ -133,6 +133,20 @@ DirectProxyHandler::setImmutablePrototype(JSContext *cx, HandleObject proxy, boo
return JSObject::setImmutablePrototype(cx, target, succeeded);
}
bool
DirectProxyHandler::preventExtensions(JSContext *cx, HandleObject proxy, bool *succeeded) const
{
RootedObject target(cx, proxy->as<ProxyObject>().target());
return JSObject::preventExtensions(cx, target, succeeded);
}
bool
DirectProxyHandler::isExtensible(JSContext *cx, HandleObject proxy, bool *extensible) const
{
RootedObject target(cx, proxy->as<ProxyObject>().target());
return JSObject::isExtensible(cx, target, extensible);
}
bool
DirectProxyHandler::objectClassIs(HandleObject proxy, ESClassValue classValue,
JSContext *cx) const
@ -243,20 +257,6 @@ DirectProxyHandler::iterate(JSContext *cx, HandleObject proxy, unsigned flags,
return GetIterator(cx, target, flags, vp);
}
bool
DirectProxyHandler::isExtensible(JSContext *cx, HandleObject proxy, bool *extensible) const
{
RootedObject target(cx, proxy->as<ProxyObject>().target());
return JSObject::isExtensible(cx, target, extensible);
}
bool
DirectProxyHandler::preventExtensions(JSContext *cx, HandleObject proxy, bool *succeeded) const
{
RootedObject target(cx, proxy->as<ProxyObject>().target());
return JSObject::preventExtensions(cx, target, succeeded);
}
bool
DirectProxyHandler::isCallable(JSObject *obj) const
{

Просмотреть файл

@ -224,6 +224,45 @@ Proxy::enumerate(JSContext *cx, HandleObject proxy, AutoIdVector &props)
AppendUnique(cx, props, protoProps));
}
/* static */ bool
Proxy::getPrototypeOf(JSContext *cx, HandleObject proxy, MutableHandleObject proto)
{
MOZ_ASSERT(proxy->hasLazyPrototype());
JS_CHECK_RECURSION(cx, return false);
return proxy->as<ProxyObject>().handler()->getPrototypeOf(cx, proxy, proto);
}
/* static */ bool
Proxy::setPrototypeOf(JSContext *cx, HandleObject proxy, HandleObject proto, bool *bp)
{
MOZ_ASSERT(proxy->hasLazyPrototype());
JS_CHECK_RECURSION(cx, return false);
return proxy->as<ProxyObject>().handler()->setPrototypeOf(cx, proxy, proto, bp);
}
/* static */ bool
Proxy::setImmutablePrototype(JSContext *cx, HandleObject proxy, bool *succeeded)
{
JS_CHECK_RECURSION(cx, return false);
const BaseProxyHandler *handler = proxy->as<ProxyObject>().handler();
return handler->setImmutablePrototype(cx, proxy, succeeded);
}
/* static */ bool
Proxy::preventExtensions(JSContext *cx, HandleObject proxy, bool *succeeded)
{
JS_CHECK_RECURSION(cx, return false);
const BaseProxyHandler *handler = proxy->as<ProxyObject>().handler();
return handler->preventExtensions(cx, proxy, succeeded);
}
/* static */ bool
Proxy::isExtensible(JSContext *cx, HandleObject proxy, bool *extensible)
{
JS_CHECK_RECURSION(cx, return false);
return proxy->as<ProxyObject>().handler()->isExtensible(cx, proxy, extensible);
}
bool
Proxy::has(JSContext *cx, HandleObject proxy, HandleId id, bool *bp)
{
@ -379,21 +418,6 @@ Proxy::iterate(JSContext *cx, HandleObject proxy, unsigned flags, MutableHandleV
return EnumeratedIdVectorToIterator(cx, proxy, flags, props, vp);
}
bool
Proxy::isExtensible(JSContext *cx, HandleObject proxy, bool *extensible)
{
JS_CHECK_RECURSION(cx, return false);
return proxy->as<ProxyObject>().handler()->isExtensible(cx, proxy, extensible);
}
bool
Proxy::preventExtensions(JSContext *cx, HandleObject proxy, bool *succeeded)
{
JS_CHECK_RECURSION(cx, return false);
const BaseProxyHandler *handler = proxy->as<ProxyObject>().handler();
return handler->preventExtensions(cx, proxy, succeeded);
}
bool
Proxy::call(JSContext *cx, HandleObject proxy, const CallArgs &args)
{
@ -517,30 +541,6 @@ Proxy::defaultValue(JSContext *cx, HandleObject proxy, JSType hint, MutableHandl
JSObject * const TaggedProto::LazyProto = reinterpret_cast<JSObject *>(0x1);
/* static */ bool
Proxy::getPrototypeOf(JSContext *cx, HandleObject proxy, MutableHandleObject proto)
{
MOZ_ASSERT(proxy->hasLazyPrototype());
JS_CHECK_RECURSION(cx, return false);
return proxy->as<ProxyObject>().handler()->getPrototypeOf(cx, proxy, proto);
}
/* static */ bool
Proxy::setPrototypeOf(JSContext *cx, HandleObject proxy, HandleObject proto, bool *bp)
{
MOZ_ASSERT(proxy->hasLazyPrototype());
JS_CHECK_RECURSION(cx, return false);
return proxy->as<ProxyObject>().handler()->setPrototypeOf(cx, proxy, proto, bp);
}
/* static */ bool
Proxy::setImmutablePrototype(JSContext *cx, HandleObject proxy, bool *succeeded)
{
JS_CHECK_RECURSION(cx, return false);
const BaseProxyHandler *handler = proxy->as<ProxyObject>().handler();
return handler->setImmutablePrototype(cx, proxy, succeeded);
}
/* static */ bool
Proxy::watch(JSContext *cx, JS::HandleObject proxy, JS::HandleId id, JS::HandleObject callable)
{

Просмотреть файл

@ -273,6 +273,50 @@ ArrayToIdVector(JSContext *cx, HandleObject proxy, HandleObject target, HandleVa
return true;
}
// ES6 implements both getPrototypeOf and setPrototypeOf traps. We don't have them yet (see bug
// 888969). For now, use these, to account for proxy revocation.
bool
ScriptedDirectProxyHandler::getPrototypeOf(JSContext *cx, HandleObject proxy,
MutableHandleObject protop) const
{
RootedObject target(cx, proxy->as<ProxyObject>().target());
// Though handler is used elsewhere, spec mandates that both get set to null.
if (!target) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_PROXY_REVOKED);
return false;
}
return DirectProxyHandler::getPrototypeOf(cx, proxy, protop);
}
bool
ScriptedDirectProxyHandler::setPrototypeOf(JSContext *cx, HandleObject proxy,
HandleObject proto, bool *bp) const
{
RootedObject target(cx, proxy->as<ProxyObject>().target());
if (!target) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_PROXY_REVOKED);
return false;
}
return DirectProxyHandler::setPrototypeOf(cx, proxy, proto, bp);
}
// Not yet part of ES6, but hopefully to be standards-tracked -- and needed to
// handle revoked proxies in any event.
bool
ScriptedDirectProxyHandler::setImmutablePrototype(JSContext *cx, HandleObject proxy,
bool *succeeded) const
{
RootedObject target(cx, proxy->as<ProxyObject>().target());
if (!target) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_PROXY_REVOKED);
return false;
}
return DirectProxyHandler::setImmutablePrototype(cx, proxy, succeeded);
}
// ES6 20141014 9.5.4 Proxy.[[PreventExtensions]]()
bool
ScriptedDirectProxyHandler::preventExtensions(JSContext *cx, HandleObject proxy,
@ -324,48 +368,56 @@ ScriptedDirectProxyHandler::preventExtensions(JSContext *cx, HandleObject proxy,
return true;
}
// ES6 implements both getPrototypeOf and setPrototypeOf traps. We don't have them yet (see bug
// 888969). For now, use these, to account for proxy revocation.
// ES6 (5 April, 2014) 9.5.3 Proxy.[[IsExtensible]]()
bool
ScriptedDirectProxyHandler::getPrototypeOf(JSContext *cx, HandleObject proxy,
MutableHandleObject protop) const
ScriptedDirectProxyHandler::isExtensible(JSContext *cx, HandleObject proxy, bool *extensible) const
{
RootedObject target(cx, proxy->as<ProxyObject>().target());
// Though handler is used elsewhere, spec mandates that both get set to null.
if (!target) {
// step 1
RootedObject handler(cx, GetDirectProxyHandlerObject(proxy));
// step 2
if (!handler) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_PROXY_REVOKED);
return false;
}
return DirectProxyHandler::getPrototypeOf(cx, proxy, protop);
}
bool
ScriptedDirectProxyHandler::setPrototypeOf(JSContext *cx, HandleObject proxy,
HandleObject proto, bool *bp) const
{
// step 3
RootedObject target(cx, proxy->as<ProxyObject>().target());
if (!target) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_PROXY_REVOKED);
// step 4-5
RootedValue trap(cx);
if (!JSObject::getProperty(cx, handler, handler, cx->names().isExtensible, &trap))
return false;
// step 6
if (trap.isUndefined())
return DirectProxyHandler::isExtensible(cx, proxy, extensible);
// step 7, 9
Value argv[] = {
ObjectValue(*target)
};
RootedValue trapResult(cx);
if (!Invoke(cx, ObjectValue(*handler), trap, ArrayLength(argv), argv, &trapResult))
return false;
// step 8
bool booleanTrapResult = ToBoolean(trapResult);
// step 10-11
bool targetResult;
if (!JSObject::isExtensible(cx, target, &targetResult))
return false;
// step 12
if (targetResult != booleanTrapResult) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_PROXY_EXTENSIBILITY);
return false;
}
return DirectProxyHandler::setPrototypeOf(cx, proxy, proto, bp);
}
// Not yet part of ES6, but hopefully to be standards-tracked -- and needed to
// handle revoked proxies in any event.
bool
ScriptedDirectProxyHandler::setImmutablePrototype(JSContext *cx, HandleObject proxy,
bool *succeeded) const
{
RootedObject target(cx, proxy->as<ProxyObject>().target());
if (!target) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_PROXY_REVOKED);
return false;
}
return DirectProxyHandler::setImmutablePrototype(cx, proxy, succeeded);
// step 13
*extensible = booleanTrapResult;
return true;
}
// Corresponds to the "standard" property descriptor getOwn getPrototypeOf dance. It's so explicit
@ -966,58 +1018,6 @@ ScriptedDirectProxyHandler::set(JSContext *cx, HandleObject proxy, HandleObject
return true;
}
// ES6 (5 April, 2014) 9.5.3 Proxy.[[IsExtensible]]()
bool
ScriptedDirectProxyHandler::isExtensible(JSContext *cx, HandleObject proxy, bool *extensible) const
{
// step 1
RootedObject handler(cx, GetDirectProxyHandlerObject(proxy));
// step 2
if (!handler) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_PROXY_REVOKED);
return false;
}
// step 3
RootedObject target(cx, proxy->as<ProxyObject>().target());
// step 4-5
RootedValue trap(cx);
if (!JSObject::getProperty(cx, handler, handler, cx->names().isExtensible, &trap))
return false;
// step 6
if (trap.isUndefined())
return DirectProxyHandler::isExtensible(cx, proxy, extensible);
// step 7, 9
Value argv[] = {
ObjectValue(*target)
};
RootedValue trapResult(cx);
if (!Invoke(cx, ObjectValue(*handler), trap, ArrayLength(argv), argv, &trapResult))
return false;
// step 8
bool booleanTrapResult = ToBoolean(trapResult);
// step 10-11
bool targetResult;
if (!JSObject::isExtensible(cx, target, &targetResult))
return false;
// step 12
if (targetResult != booleanTrapResult) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_PROXY_EXTENSIBILITY);
return false;
}
// step 13
*extensible = booleanTrapResult;
return true;
}
bool
ScriptedDirectProxyHandler::iterate(JSContext *cx, HandleObject proxy, unsigned flags,
MutableHandleValue vp) const

Просмотреть файл

@ -27,8 +27,6 @@ class ScriptedDirectProxyHandler : public DirectProxyHandler {
AutoIdVector &props) const MOZ_OVERRIDE;
virtual bool delete_(JSContext *cx, HandleObject proxy, HandleId id, bool *bp) const MOZ_OVERRIDE;
virtual bool enumerate(JSContext *cx, HandleObject proxy, AutoIdVector &props) const MOZ_OVERRIDE;
virtual bool isExtensible(JSContext *cx, HandleObject proxy, bool *extensible) const MOZ_OVERRIDE;
virtual bool preventExtensions(JSContext *cx, HandleObject proxy, bool *succeeded) const MOZ_OVERRIDE;
/* These two are standard internal methods but aren't implemented to spec yet. */
virtual bool getPrototypeOf(JSContext *cx, HandleObject proxy,
@ -39,6 +37,9 @@ class ScriptedDirectProxyHandler : public DirectProxyHandler {
virtual bool setImmutablePrototype(JSContext *cx, HandleObject proxy,
bool *succeeded) const MOZ_OVERRIDE;
virtual bool preventExtensions(JSContext *cx, HandleObject proxy, bool *succeeded) const MOZ_OVERRIDE;
virtual bool isExtensible(JSContext *cx, HandleObject proxy, bool *extensible) const MOZ_OVERRIDE;
virtual bool has(JSContext *cx, HandleObject proxy, HandleId id, bool *bp) const MOZ_OVERRIDE;
virtual bool get(JSContext *cx, HandleObject proxy, HandleObject receiver, HandleId id,
MutableHandleValue vp) const MOZ_OVERRIDE;

Просмотреть файл

@ -130,6 +130,14 @@ static const Class CallConstructHolder = {
// This variable exists solely to provide a unique address for use as an identifier.
const char ScriptedIndirectProxyHandler::family = 0;
bool
ScriptedIndirectProxyHandler::preventExtensions(JSContext *cx, HandleObject proxy, bool *succeeded) const
{
// See above.
*succeeded = false;
return true;
}
bool
ScriptedIndirectProxyHandler::isExtensible(JSContext *cx, HandleObject proxy,
bool *extensible) const
@ -139,14 +147,6 @@ ScriptedIndirectProxyHandler::isExtensible(JSContext *cx, HandleObject proxy,
return true;
}
bool
ScriptedIndirectProxyHandler::preventExtensions(JSContext *cx, HandleObject proxy, bool *succeeded) const
{
// See above.
*succeeded = false;
return true;
}
static bool
ReturnedValueMustNotBePrimitive(JSContext *cx, HandleObject proxy, JSAtom *atom, const Value &v)
{

Просмотреть файл

@ -28,8 +28,8 @@ class ScriptedIndirectProxyHandler : public BaseProxyHandler
AutoIdVector &props) const MOZ_OVERRIDE;
virtual bool delete_(JSContext *cx, HandleObject proxy, HandleId id, bool *bp) const MOZ_OVERRIDE;
virtual bool enumerate(JSContext *cx, HandleObject proxy, AutoIdVector &props) const MOZ_OVERRIDE;
virtual bool isExtensible(JSContext *cx, HandleObject proxy, bool *extensible) const MOZ_OVERRIDE;
virtual bool preventExtensions(JSContext *cx, HandleObject proxy, bool *succeeded) const MOZ_OVERRIDE;
virtual bool isExtensible(JSContext *cx, HandleObject proxy, bool *extensible) const MOZ_OVERRIDE;
virtual bool has(JSContext *cx, HandleObject proxy, HandleId id, bool *bp) const MOZ_OVERRIDE;
virtual bool get(JSContext *cx, HandleObject proxy, HandleObject receiver, HandleId id,
MutableHandleValue vp) const MOZ_OVERRIDE;

Просмотреть файл

@ -11,27 +11,6 @@
using namespace js;
template <class Base>
bool
SecurityWrapper<Base>::isExtensible(JSContext *cx, HandleObject wrapper, bool *extensible) const
{
// Just like BaseProxyHandler, SecurityWrappers claim by default to always
// be extensible, so as not to leak information about the state of the
// underlying wrapped thing.
*extensible = true;
return true;
}
template <class Base>
bool
SecurityWrapper<Base>::preventExtensions(JSContext *cx, HandleObject wrapper,
bool *succeeded) const
{
// See above.
*succeeded = false;
return true;
}
template <class Base>
bool
SecurityWrapper<Base>::enter(JSContext *cx, HandleObject wrapper, HandleId id,
@ -51,6 +30,15 @@ SecurityWrapper<Base>::nativeCall(JSContext *cx, IsAcceptableThis test, NativeIm
return false;
}
template <class Base>
bool
SecurityWrapper<Base>::setPrototypeOf(JSContext *cx, HandleObject wrapper,
HandleObject proto, bool *bp) const
{
JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_UNWRAP_DENIED);
return false;
}
template <class Base>
bool
SecurityWrapper<Base>::setImmutablePrototype(JSContext *cx, HandleObject wrapper,
@ -62,11 +50,23 @@ SecurityWrapper<Base>::setImmutablePrototype(JSContext *cx, HandleObject wrapper
template <class Base>
bool
SecurityWrapper<Base>::setPrototypeOf(JSContext *cx, HandleObject wrapper,
HandleObject proto, bool *bp) const
SecurityWrapper<Base>::preventExtensions(JSContext *cx, HandleObject wrapper,
bool *succeeded) const
{
JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_UNWRAP_DENIED);
return false;
// Just like BaseProxyHandler, SecurityWrappers claim by default to always
// be extensible, so as not to leak information about the state of the
// underlying wrapped thing.
*succeeded = false;
return true;
}
template <class Base>
bool
SecurityWrapper<Base>::isExtensible(JSContext *cx, HandleObject wrapper, bool *extensible) const
{
// See above.
*extensible = true;
return true;
}
// For security wrappers, we run the DefaultValue algorithm on the wrapper

Просмотреть файл

@ -1505,18 +1505,18 @@ class DebugScopeProxy : public BaseProxyHandler
MOZ_CONSTEXPR DebugScopeProxy() : BaseProxyHandler(&family) {}
bool isExtensible(JSContext *cx, HandleObject proxy, bool *extensible) const MOZ_OVERRIDE
bool preventExtensions(JSContext *cx, HandleObject proxy, bool *succeeded) const MOZ_OVERRIDE
{
// always [[Extensible]], can't be made non-[[Extensible]], like most
// proxies
*extensible = true;
*succeeded = false;
return true;
}
bool preventExtensions(JSContext *cx, HandleObject proxy, bool *succeeded) const MOZ_OVERRIDE
bool isExtensible(JSContext *cx, HandleObject proxy, bool *extensible) const MOZ_OVERRIDE
{
// See above.
*succeeded = false;
*extensible = true;
return true;
}

Просмотреть файл

@ -1745,25 +1745,25 @@ XrayToString(JSContext *cx, unsigned argc, Value *vp)
template <typename Base, typename Traits>
bool
XrayWrapper<Base, Traits>::isExtensible(JSContext *cx, JS::Handle<JSObject*> wrapper,
bool *extensible) const
XrayWrapper<Base, Traits>::preventExtensions(JSContext *cx, HandleObject wrapper, bool *succeeded)
const
{
// Xray wrappers are supposed to provide a clean view of the target
// reflector, hiding any modifications by script in the target scope. So
// even if that script freezes the reflector, we don't want to make that
// visible to the caller. DOM reflectors are always extensible by default,
// so we can just return true here.
*extensible = true;
*succeeded = false;
return true;
}
template <typename Base, typename Traits>
bool
XrayWrapper<Base, Traits>::preventExtensions(JSContext *cx, HandleObject wrapper, bool *succeeded)
const
XrayWrapper<Base, Traits>::isExtensible(JSContext *cx, JS::Handle<JSObject*> wrapper,
bool *extensible) const
{
// See above.
*succeeded = false;
*extensible = true;
return true;
}

Просмотреть файл

@ -414,14 +414,14 @@ class XrayWrapper : public Base {
virtual bool delete_(JSContext *cx, JS::Handle<JSObject*> wrapper,
JS::Handle<jsid> id, bool *bp) const MOZ_OVERRIDE;
virtual bool enumerate(JSContext *cx, JS::Handle<JSObject*> wrapper, JS::AutoIdVector &props) const MOZ_OVERRIDE;
virtual bool isExtensible(JSContext *cx, JS::Handle<JSObject*> wrapper, bool *extensible) const MOZ_OVERRIDE;
virtual bool preventExtensions(JSContext *cx, JS::Handle<JSObject*> wrapper, bool *succeeded) const MOZ_OVERRIDE;
virtual bool getPrototypeOf(JSContext *cx, JS::HandleObject wrapper,
JS::MutableHandleObject protop) const MOZ_OVERRIDE;
virtual bool setPrototypeOf(JSContext *cx, JS::HandleObject wrapper,
JS::HandleObject proto, bool *bp) const MOZ_OVERRIDE;
virtual bool setImmutablePrototype(JSContext *cx, JS::HandleObject wrapper,
bool *succeeded) const MOZ_OVERRIDE;
virtual bool preventExtensions(JSContext *cx, JS::Handle<JSObject*> wrapper, bool *succeeded) const MOZ_OVERRIDE;
virtual bool isExtensible(JSContext *cx, JS::Handle<JSObject*> wrapper, bool *extensible) const MOZ_OVERRIDE;
virtual bool has(JSContext *cx, JS::Handle<JSObject*> wrapper, JS::Handle<jsid> id,
bool *bp) const MOZ_OVERRIDE;
virtual bool get(JSContext *cx, JS::Handle<JSObject*> wrapper, JS::Handle<JSObject*> receiver,