Bug 978235 - ES6 Proxies: Implement [[IsExtensible]] trap. (r=jorendorff)

This commit is contained in:
Eric Faust 2014-04-15 13:13:51 -07:00
Родитель 00fc6e1f7e
Коммит 86d8c855a7
3 изменённых файлов: 51 добавлений и 6 удалений

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

@ -437,3 +437,4 @@ MSG_DEF(JSMSG_SETPROTOTYPEOF_FAIL, 382, 1, JSEXN_TYPEERR, "[[SetPrototypeOf
MSG_DEF(JSMSG_INVALID_ARG_TYPE, 383, 3, JSEXN_TYPEERR, "Invalid type: {0} can't be a{1} {2}")
MSG_DEF(JSMSG_TERMINATED, 384, 1, JSEXN_ERR, "Script terminated by timeout at:\n{0}")
MSG_DEF(JSMSG_NO_SUCH_SELF_HOSTED_PROP, 385, 1, JSEXN_ERR, "No such property on self-hosted object: {0}")
MSG_DEF(JSMSG_PROXY_EXTENSIBILITY, 386, 0, JSEXN_TYPEERR, "proxy must report same extensiblitity as target")

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

@ -1077,12 +1077,6 @@ ScriptedIndirectProxyHandler::fun_toString(JSContext *cx, HandleObject proxy, un
ScriptedIndirectProxyHandler ScriptedIndirectProxyHandler::singleton;
static JSObject *
GetDirectProxyHandlerObject(JSObject *proxy)
{
return proxy->as<ProxyObject>().extra(0).toObjectOrNull();
}
/* Derived class for all scripted direct proxy handlers. */
class ScriptedDirectProxyHandler : public DirectProxyHandler {
public:
@ -1114,6 +1108,9 @@ class ScriptedDirectProxyHandler : public DirectProxyHandler {
virtual bool iterate(JSContext *cx, HandleObject proxy, unsigned flags,
MutableHandleValue vp) MOZ_OVERRIDE;
/* ES6 Harmony traps */
virtual bool isExtensible(JSContext *cx, HandleObject proxy, bool *extensible) MOZ_OVERRIDE;
/* Spidermonkey extensions. */
virtual bool call(JSContext *cx, HandleObject proxy, const CallArgs &args) MOZ_OVERRIDE;
virtual bool construct(JSContext *cx, HandleObject proxy, const CallArgs &args) MOZ_OVERRIDE;
@ -1365,6 +1362,16 @@ IdToValue(JSContext *cx, HandleId id, MutableHandleValue value)
return true;
}
// Get the [[ProxyHandler]] of a scripted direct proxy.
//
// NB: This *must* stay synched with proxy().
static JSObject *
GetDirectProxyHandlerObject(JSObject *proxy)
{
JS_ASSERT(proxy->as<ProxyObject>().handler() == &ScriptedDirectProxyHandler::singleton);
return proxy->as<ProxyObject>().extra(0).toObjectOrNull();
}
// TrapGetOwnProperty(O, P)
static bool
TrapGetOwnProperty(JSContext *cx, HandleObject proxy, HandleId id, MutableHandleValue rval)
@ -2225,6 +2232,42 @@ ScriptedDirectProxyHandler::keys(JSContext *cx, HandleObject proxy, AutoIdVector
return ArrayToIdVector(cx, proxy, target, trapResult, props, JSITER_OWNONLY, cx->names().keys);
}
// ES6 (5 April, 2014) 9.5.3 Proxy.[[IsExtensible]](P)
bool
ScriptedDirectProxyHandler::isExtensible(JSContext *cx, HandleObject proxy, bool *extensible)
{
RootedObject handler(cx, GetDirectProxyHandlerObject(proxy));
RootedObject target(cx, proxy->as<ProxyObject>().target());
RootedValue trap(cx);
if (!JSObject::getProperty(cx, handler, handler, cx->names().isExtensible, &trap))
return false;
if (trap.isUndefined())
return DirectProxyHandler::isExtensible(cx, proxy, extensible);
Value argv[] = {
ObjectValue(*target)
};
RootedValue trapResult(cx);
if (!Invoke(cx, ObjectValue(*handler), trap, ArrayLength(argv), argv, &trapResult))
return false;
bool booleanTrapResult = ToBoolean(trapResult);
bool targetResult;
if (!JSObject::isExtensible(cx, target, &targetResult))
return false;
if (targetResult != booleanTrapResult) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_PROXY_EXTENSIBILITY);
return false;
}
*extensible = booleanTrapResult;
return true;
}
bool
ScriptedDirectProxyHandler::iterate(JSContext *cx, HandleObject proxy, unsigned flags,
MutableHandleValue vp)

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

@ -103,6 +103,7 @@
macro(int8, int8, "int8") \
macro(int16, int16, "int16") \
macro(int32, int32, "int32") \
macro(isExtensible, isExtensible, "isExtensible") \
macro(iterator, iterator, "iterator") \
macro(iteratorIntrinsic, iteratorIntrinsic, "__iterator__") \
macro(join, join, "join") \