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/GlobalObject.cpp | |
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/GlobalObject.cpp')
-rw-r--r-- | js/src/vm/GlobalObject.cpp | 32 |
1 files changed, 32 insertions, 0 deletions
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; |