diff options
author | wolfbeast <mcwerewolf@wolfbeast.com> | 2020-05-30 21:14:43 +0200 |
---|---|---|
committer | Moonchild <moonchild@palemoon.org> | 2020-06-01 11:48:07 +0000 |
commit | 86187199216ea46d879f35b93d7731185bdc598e (patch) | |
tree | 2eb8cf214b8d2020a364bcf01b7ecb030101098e /js/src/vm | |
parent | b6db7da98af264b55161bc93e6020fe404cfc627 (diff) | |
download | UXP-86187199216ea46d879f35b93d7731185bdc598e.tar UXP-86187199216ea46d879f35b93d7731185bdc598e.tar.gz UXP-86187199216ea46d879f35b93d7731185bdc598e.tar.lz UXP-86187199216ea46d879f35b93d7731185bdc598e.tar.xz UXP-86187199216ea46d879f35b93d7731185bdc598e.zip |
Issue #1570 - Implement globalThis
This resolves #1570
Diffstat (limited to 'js/src/vm')
-rw-r--r-- | js/src/vm/CommonPropertyNames.h | 1 | ||||
-rw-r--r-- | js/src/vm/GlobalObject.cpp | 32 | ||||
-rw-r--r-- | js/src/vm/GlobalObject.h | 3 |
3 files changed, 36 insertions, 0 deletions
diff --git a/js/src/vm/CommonPropertyNames.h b/js/src/vm/CommonPropertyNames.h index 420ee7535..b4a2de6f3 100644 --- a/js/src/vm/CommonPropertyNames.h +++ b/js/src/vm/CommonPropertyNames.h @@ -160,6 +160,7 @@ macro(getPropertyDescriptor, getPropertyDescriptor, "getPropertyDescriptor") \ macro(getPrototypeOf, getPrototypeOf, "getPrototypeOf") \ macro(global, global, "global") \ + macro(globalThis, globalThis, "globalThis") \ macro(Handle, Handle, "Handle") \ macro(has, has, "has") \ macro(hasOwn, hasOwn, "hasOwn") \ diff --git a/js/src/vm/GlobalObject.cpp b/js/src/vm/GlobalObject.cpp index a8d401af4..f6a53eef4 100644 --- a/js/src/vm/GlobalObject.cpp +++ b/js/src/vm/GlobalObject.cpp @@ -296,6 +296,32 @@ GlobalObject::initBuiltinConstructor(JSContext* cx, Handle<GlobalObject*> global return true; } +// Resolve a "globalThis" self-referential property if necessary, +// per a stage-3 proposal. https://github.com/tc39/ecma262/pull/702 +// +// We could also do this in |FinishObjectClassInit| to trim the global +// resolve hook. Unfortunately, |ToWindowProxyIfWindow| doesn't work then: +// the browser's |nsGlobalWindow::SetNewDocument| invokes Object init +// *before* it sets the global's WindowProxy using |js::SetWindowProxy|. +// +// Refactoring global object creation code to support this approach is a +// challenge for another day. +/* static */ bool +GlobalObject::maybeResolveGlobalThis(JSContext* cx, Handle<GlobalObject*> global, bool* resolved) +{ + if (global->getSlot(GLOBAL_THIS_RESOLVED).isUndefined()) { + RootedValue v(cx, ObjectValue(*ToWindowProxyIfWindow(global))); + if (!DefineProperty(cx, global, cx->names().globalThis, v, nullptr, nullptr, JSPROP_RESOLVING)) { + return false; + } + + *resolved = true; + global->setSlot(GLOBAL_THIS_RESOLVED, BooleanValue(true)); + } + + return true; +} + GlobalObject* GlobalObject::createInternal(JSContext* cx, const Class* clasp) { @@ -419,6 +445,12 @@ GlobalObject::initStandardClasses(JSContext* cx, Handle<GlobalObject*> global) return false; } + // Resolve a "globalThis" self-referential property if necessary. + bool resolved; + if (!GlobalObject::maybeResolveGlobalThis(cx, global, &resolved)) { + return false; + } + for (size_t k = 0; k < JSProto_LIMIT; ++k) { if (!ensureConstructor(cx, global, static_cast<JSProtoKey>(k))) return false; diff --git a/js/src/vm/GlobalObject.h b/js/src/vm/GlobalObject.h index 3fd2762f8..720f63e69 100644 --- a/js/src/vm/GlobalObject.h +++ b/js/src/vm/GlobalObject.h @@ -121,6 +121,7 @@ class GlobalObject : public NativeObject FOR_OF_PIC_CHAIN, MODULE_RESOLVE_HOOK, WINDOW_PROXY, + GLOBAL_THIS_RESOLVED, /* Total reserved-slot count for global objects. */ RESERVED_SLOTS @@ -171,6 +172,8 @@ class GlobalObject : public NativeObject static bool initBuiltinConstructor(JSContext* cx, Handle<GlobalObject*> global, JSProtoKey key, HandleObject ctor, HandleObject proto); + static bool maybeResolveGlobalThis(JSContext* cx, Handle<GlobalObject*> global, bool* resolved); + void setConstructor(JSProtoKey key, const Value& v) { MOZ_ASSERT(key <= JSProto_LIMIT); setSlot(APPLICATION_SLOTS + key, v); |