Issue #1570 - Implement globalThis

This resolves #1570
This commit is contained in:
wolfbeast 2020-05-30 21:14:43 +02:00 committed by Roy Tam
commit 5386cd812b
5 changed files with 44 additions and 3 deletions

View file

@ -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;