From ec64edae213019f8fd0ecc58dace3e439e0a635a Mon Sep 17 00:00:00 2001 From: Lauren Tan Date: Tue, 15 Nov 2022 13:32:53 -0500 Subject: [PATCH] Create identifier for any global or unscoped variable Noticed this while running test262 tests that many variables were throwing an invariant for being undefined. This includes things like the special `arguments` object, a global `assert` function used by test262, etc. --- compiler/forget/src/HIR/BuildHIR.ts | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/compiler/forget/src/HIR/BuildHIR.ts b/compiler/forget/src/HIR/BuildHIR.ts index 7538415039..9fd95e0570 100644 --- a/compiler/forget/src/HIR/BuildHIR.ts +++ b/compiler/forget/src/HIR/BuildHIR.ts @@ -38,6 +38,18 @@ const GLOBALS: Map = new Map([ ["Math", t.identifier("Math")], ]); +// TODO: This will work as a stopgap but it isn't really correct. We need proper handling of globals +// and module-scoped variables, which means understanding module constants and imports. +function getOrAddGlobal(identifierName: string): t.Identifier { + const ident = GLOBALS.get(identifierName); + if (ident != null) { + return ident; + } + const newIdent = t.identifier(identifierName); + GLOBALS.set(identifierName, newIdent); + return newIdent; +} + /** * Lower a function declaration into a control flow graph that models aspects of * control flow that are necessary for memoization. Notably, only control flow @@ -1095,7 +1107,7 @@ function lowerJsxElementName( const tag: string = exprPath.node.name; if (tag.match(/^[A-Z]/)) { const binding = - exprPath.scope.getBindingIdentifier(tag) ?? GLOBALS.get(tag); + exprPath.scope.getBindingIdentifier(tag) ?? getOrAddGlobal(tag); invariant( binding != null, `Expected to find a binding for variable '%s'`, @@ -1229,7 +1241,7 @@ function lowerLVal(builder: HIRBuilder, exprPath: NodePath): Place { // const name: string = expr.get("name"); const binding = exprPath.scope.getBindingIdentifier(exprNode.name) ?? - GLOBALS.get(exprNode.name); + getOrAddGlobal(exprNode.name); invariant( binding != null, `Expected to find a binding for variable '%s'`,