Bug 1192297 - Rephrase Proxy static methods to make it clearer that the handler->hasPrototype() case is the weird case. r=Waldo.

--HG--
extra : commitid : ESIC2Z4wS6J
extra : rebase_source : 9cde8160d79fe11317ed59b8df86454dcae605cc
This commit is contained in:
Jason Orendorff 2015-08-07 10:00:02 -05:00
Родитель c83b792e35
Коммит 90259502e7
1 изменённых файлов: 62 добавлений и 59 удалений

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

@ -88,17 +88,6 @@ js::assertEnteredPolicy(JSContext* cx, JSObject* proxy, jsid id,
}
#endif
#define INVOKE_ON_PROTOTYPE(cx, handler, proxy, protoCall) \
JS_BEGIN_MACRO \
RootedObject proto(cx); \
if (!GetPrototype(cx, proxy, &proto)) \
return false; \
if (!proto) \
return true; \
assertSameCompartment(cx, proxy, proto); \
return protoCall; \
JS_END_MACRO \
bool
Proxy::getPropertyDescriptor(JSContext* cx, HandleObject proxy, HandleId id,
MutableHandle<PropertyDescriptor> desc)
@ -109,13 +98,12 @@ Proxy::getPropertyDescriptor(JSContext* cx, HandleObject proxy, HandleId id,
AutoEnterPolicy policy(cx, handler, proxy, id, BaseProxyHandler::GET_PROPERTY_DESCRIPTOR, true);
if (!policy.allowed())
return policy.returnValue();
if (!handler->hasPrototype())
return handler->getPropertyDescriptor(cx, proxy, id, desc);
if (!handler->getOwnPropertyDescriptor(cx, proxy, id, desc))
return false;
if (desc.object())
return true;
INVOKE_ON_PROTOTYPE(cx, handler, proxy, GetPropertyDescriptor(cx, proto, id, desc));
// Special case. See the comment on BaseProxyHandler::mHasPrototype.
if (handler->hasPrototype())
return handler->BaseProxyHandler::getPropertyDescriptor(cx, proxy, id, desc);
return handler->getPropertyDescriptor(cx, proxy, id, desc);
}
bool
@ -241,16 +229,23 @@ Proxy::has(JSContext* cx, HandleObject proxy, HandleId id, bool* bp)
AutoEnterPolicy policy(cx, handler, proxy, id, BaseProxyHandler::GET, true);
if (!policy.allowed())
return policy.returnValue();
if (!handler->hasPrototype())
return handler->has(cx, proxy, id, bp);
if (!handler->hasOwn(cx, proxy, id, bp))
return false;
if (*bp)
return true;
bool Bp;
INVOKE_ON_PROTOTYPE(cx, handler, proxy,
JS_HasPropertyById(cx, proto, id, &Bp) &&
((*bp = Bp) || true));
if (handler->hasPrototype()) {
if (!handler->hasOwn(cx, proxy, id, bp))
return false;
if (*bp)
return true;
RootedObject proto(cx);
if (!GetPrototype(cx, proxy, &proto))
return false;
if (!proto)
return true;
return HasProperty(cx, proto, id, bp);
}
return handler->has(cx, proxy, id, bp);
}
bool
@ -275,16 +270,22 @@ Proxy::get(JSContext* cx, HandleObject proxy, HandleObject receiver, HandleId id
AutoEnterPolicy policy(cx, handler, proxy, id, BaseProxyHandler::GET, true);
if (!policy.allowed())
return policy.returnValue();
bool own;
if (!handler->hasPrototype()) {
own = true;
} else {
if (handler->hasPrototype()) {
bool own;
if (!handler->hasOwn(cx, proxy, id, &own))
return false;
if (!own) {
RootedObject proto(cx);
if (!GetPrototype(cx, proxy, &proto))
return false;
if (!proto)
return true;
return GetProperty(cx, proto, receiver, id, vp);
}
}
if (own)
return handler->get(cx, proxy, receiver, id, vp);
INVOKE_ON_PROTOTYPE(cx, handler, proxy, GetProperty(cx, proto, receiver, id, vp));
return handler->get(cx, proxy, receiver, id, vp);
}
bool
@ -343,33 +344,35 @@ Proxy::enumerate(JSContext* cx, HandleObject proxy, MutableHandleObject objp)
JS_CHECK_RECURSION(cx, return false);
const BaseProxyHandler* handler = proxy->as<ProxyObject>().handler();
objp.set(nullptr); // default result if we refuse to perform this action
if (!handler->hasPrototype()) {
AutoEnterPolicy policy(cx, handler, proxy, JSID_VOIDHANDLE,
BaseProxyHandler::ENUMERATE, true);
// If the policy denies access but wants us to return true, we need
// to hand a valid (empty) iterator object to the caller.
if (!policy.allowed()) {
return policy.returnValue() &&
NewEmptyPropertyIterator(cx, 0, objp);
}
return handler->enumerate(cx, proxy, objp);
if (handler->hasPrototype()) {
AutoIdVector props(cx);
if (!Proxy::getOwnEnumerablePropertyKeys(cx, proxy, props))
return false;
RootedObject proto(cx);
if (!GetPrototype(cx, proxy, &proto))
return false;
if (!proto)
return EnumeratedIdVectorToIterator(cx, proxy, 0, props, objp);
assertSameCompartment(cx, proxy, proto);
AutoIdVector protoProps(cx);
return GetPropertyKeys(cx, proto, 0, &protoProps) &&
AppendUnique(cx, props, protoProps) &&
EnumeratedIdVectorToIterator(cx, proxy, 0, props, objp);
}
AutoIdVector props(cx);
if (!Proxy::getOwnEnumerablePropertyKeys(cx, proxy, props))
return false;
AutoEnterPolicy policy(cx, handler, proxy, JSID_VOIDHANDLE,
BaseProxyHandler::ENUMERATE, true);
RootedObject proto(cx);
if (!GetPrototype(cx, proxy, &proto))
return false;
if (!proto)
return EnumeratedIdVectorToIterator(cx, proxy, 0, props, objp);
assertSameCompartment(cx, proxy, proto);
AutoIdVector protoProps(cx);
return GetPropertyKeys(cx, proto, 0, &protoProps) &&
AppendUnique(cx, props, protoProps) &&
EnumeratedIdVectorToIterator(cx, proxy, 0, props, objp);
// If the policy denies access but wants us to return true, we need
// to hand a valid (empty) iterator object to the caller.
if (!policy.allowed()) {
return policy.returnValue() &&
NewEmptyPropertyIterator(cx, 0, objp);
}
return handler->enumerate(cx, proxy, objp);
}
bool