Bug 1595745 - Part 10: Change Proxy to use ClassSpec. r=mgaudet

Proxy JSClasses are defined through a special macro (`PROXY_CLASS_DEF`), which
ensures all Proxy related bits are set correctly. The macro doesn't allow to
specify a ClassSpec, so we need to add a new macro which supports that
functionality.

Differential Revision: https://phabricator.services.mozilla.com/D52666

--HG--
extra : moz-landing-system : lando
This commit is contained in:
André Bargull 2019-11-15 17:42:55 +00:00
Родитель dfc558b12e
Коммит 8d8f78e33b
4 изменённых файлов: 17 добавлений и 31 удалений

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

@ -86,7 +86,7 @@
REAL(BigInt64Array, InitViaClassSpec, TYPED_ARRAY_CLASP(BigInt64)) \
REAL(BigUint64Array, InitViaClassSpec, TYPED_ARRAY_CLASP(BigUint64)) \
REAL(BigInt, InitViaClassSpec, OCLASP(BigInt)) \
REAL(Proxy, InitProxyClass, &js::ProxyClass) \
REAL(Proxy, InitViaClassSpec, CLASP(Proxy)) \
REAL(WeakMap, InitViaClassSpec, OCLASP(WeakMap)) \
REAL(Map, InitViaClassSpec, OCLASP(Map)) \
REAL(Set, InitViaClassSpec, OCLASP(Set)) \

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

@ -725,15 +725,18 @@ constexpr unsigned CheckProxyFlags() {
return Flags;
}
#define PROXY_CLASS_DEF(name, flags) \
#define PROXY_CLASS_DEF_WITH_CLASS_SPEC(name, flags, classSpec) \
{ \
name, \
JSClass::NON_NATIVE | JSCLASS_IS_PROXY | \
JSCLASS_DELAY_METADATA_BUILDER | js::CheckProxyFlags<flags>(), \
&js::ProxyClassOps, JS_NULL_CLASS_SPEC, &js::ProxyClassExtension, \
&js::ProxyClassOps, classSpec, &js::ProxyClassExtension, \
&js::ProxyObjectOps \
}
#define PROXY_CLASS_DEF(name, flags) \
PROXY_CLASS_DEF_WITH_CLASS_SPEC(name, flags, JS_NULL_CLASS_SPEC)
// Converts a proxy into a DeadObjectProxy that will throw exceptions on all
// access. This will run the proxy's finalizer to perform clean-up before the
// conversion happens.

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

@ -753,9 +753,17 @@ const ObjectOps js::ProxyObjectOps = {
proxy_DeleteProperty, Proxy::getElements,
Proxy::fun_toString};
const JSClass js::ProxyClass =
PROXY_CLASS_DEF("Proxy", JSCLASS_HAS_CACHED_PROTO(JSProto_Proxy) |
JSCLASS_HAS_RESERVED_SLOTS(2));
static const JSFunctionSpec proxy_static_methods[] = {
JS_FN("revocable", proxy_revocable, 2, 0), JS_FS_END};
static const ClassSpec ProxyClassSpec = {
GenericCreateConstructor<js::proxy, 2, gc::AllocKind::FUNCTION>, nullptr,
proxy_static_methods, nullptr};
const JSClass js::ProxyClass = PROXY_CLASS_DEF_WITH_CLASS_SPEC(
"Proxy",
JSCLASS_HAS_CACHED_PROTO(JSProto_Proxy) | JSCLASS_HAS_RESERVED_SLOTS(2),
&ProxyClassSpec);
JS_FRIEND_API JSObject* js::NewProxyObject(JSContext* cx,
const BaseProxyHandler* handler,
@ -794,24 +802,3 @@ void ProxyObject::renew(const BaseProxyHandler* handler, const Value& priv) {
setReservedSlot(i, UndefinedValue());
}
}
JSObject* js::InitProxyClass(JSContext* cx, Handle<GlobalObject*> global) {
static const JSFunctionSpec static_methods[] = {
JS_FN("revocable", proxy_revocable, 2, 0), JS_FS_END};
RootedFunction ctor(cx);
ctor = GlobalObject::createConstructor(cx, proxy, cx->names().Proxy, 2);
if (!ctor) {
return nullptr;
}
if (!JS_DefineFunctions(cx, ctor, static_methods)) {
return nullptr;
}
if (!JS_DefineProperty(cx, global, "Proxy", ctor, JSPROP_RESOLVING)) {
return nullptr;
}
global->setConstructor(JSProto_Proxy, ObjectValue(*ctor));
return ctor;
}

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

@ -13,8 +13,6 @@
namespace js {
class GlobalObject;
/*
* Dispatch point for handlers that executes the appropriate C++ or scripted
* traps.
@ -111,8 +109,6 @@ bool ProxySetProperty(JSContext* cx, HandleObject proxy, HandleId id,
bool ProxySetPropertyByValue(JSContext* cx, HandleObject proxy,
HandleValue idVal, HandleValue val, bool strict);
extern JSObject* InitProxyClass(JSContext* cx, Handle<GlobalObject*> global);
} /* namespace js */
#endif /* proxy_Proxy_h */