diff --git a/lib/Parser/Hash.h b/lib/Parser/Hash.h index 68140d26b28..70b4f997703 100644 --- a/lib/Parser/Hash.h +++ b/lib/Parser/Hash.h @@ -27,12 +27,12 @@ ULONG CaseInsensitiveComputeHash(LPCOLESTR posz); enum { - fidNil = 0x0000, - fidKwdRsvd = 0x0001, // the keyword is a reserved word - fidKwdFutRsvd = 0x0002, // a future reserved word, but only in strict mode + fidNil = 0x0000, + fidKwdRsvd = 0x0001, // the keyword is a reserved word + fidKwdFutRsvd = 0x0002, // a future reserved word, but only in strict mode // Flags to identify tracked aliases of "eval" - fidEval = 0x0008, + fidEval = 0x0008, // Flags to identify tracked aliases of "let" fidLetOrConst = 0x0010, // ID has previously been used in a block-scoped declaration @@ -40,10 +40,11 @@ enum // CountDcls sets the bit as it walks through the var decls so that // it can skip duplicates. FillDcls clears the bit as it walks through // again to skip duplicates. - fidGlobalDcl = 0x2000, + fidGlobalDcl = 0x2000, - fidUsed = 0x4000 // name referenced by source code + fidUsed = 0x4000, // name referenced by source code + fidModuleExport = 0x8000 // name is module export }; struct BlockIdsStack @@ -84,8 +85,6 @@ struct PidRefStack bool IsAssignment() const { return isAsg; } bool IsDynamicBinding() const { return isDynamic; } void SetDynamicBinding() { isDynamic = true; } - bool IsModuleExport() const { return isModuleExport; } - void SetModuleExport() { isModuleExport = true; } Symbol **GetSymRef() { @@ -283,6 +282,9 @@ struct Ident void SetIsLetOrConst() { m_grfid |= fidLetOrConst; } BOOL GetIsLetOrConst() const { return m_grfid & fidLetOrConst; } + + void SetIsModuleExport() { m_grfid |= fidModuleExport; } + BOOL GetIsModuleExport() const { return m_grfid & fidModuleExport; } }; diff --git a/lib/Parser/Parse.cpp b/lib/Parser/Parse.cpp index 8c6f1f0c0de..0aa8f6596fd 100644 --- a/lib/Parser/Parse.cpp +++ b/lib/Parser/Parse.cpp @@ -1368,15 +1368,6 @@ ParseNodePtr Parser::CreateModuleImportDeclNode(IdentPtr localName) return declNode; } -void Parser::MarkIdentifierReferenceIsModuleExport(IdentPtr localName) -{ - PidRefStack* pidRef = this->PushPidRef(localName); - - Assert(pidRef != nullptr); - - pidRef->SetModuleExport(); -} - ParseNodePtr Parser::CreateVarDeclNode(IdentPtr pid, SymbolType symbolType, bool autoArgumentsObject, ParseNodePtr pnodeFnc, bool errorOnRedecl) { ParseNodePtr pnode = CreateDeclNode(knopVarDecl, pid, symbolType, errorOnRedecl); @@ -1679,6 +1670,11 @@ void Parser::BindPidRefsInScope(IdentPtr pid, Symbol *sym, int blockId, uint max Js::LocalFunctionId funcId = GetCurrentFunctionNode()->sxFnc.functionId; Assert(sym); + if (pid->GetIsModuleExport()) + { + sym->SetIsModuleExportStorage(true); + } + for (ref = pid->GetTopRef(); ref && ref->GetScopeId() >= blockId; ref = nextRef) { // Fix up sym* on PID ref. @@ -1702,11 +1698,6 @@ void Parser::BindPidRefsInScope(IdentPtr pid, Symbol *sym, int blockId, uint max } } - if (ref->IsModuleExport()) - { - sym->SetIsModuleExportStorage(true); - } - if (ref->GetFuncScopeId() != funcId && !sym->GetIsGlobal() && !sym->GetIsModuleExportStorage()) { Assert(ref->GetFuncScopeId() > funcId); @@ -2142,7 +2133,7 @@ void Parser::ParseNamedImportOrExportClause(ModuleImportOrExportEntryList* impor } else { - MarkIdentifierReferenceIsModuleExport(identifierName); + identifierName->SetIsModuleExport(); AddModuleImportOrExportEntry(importOrExportEntryList, nullptr, identifierName, identifierAs, nullptr); } } diff --git a/test/es6/module-functionality.js b/test/es6/module-functionality.js index bf91b582083..45b73736714 100644 --- a/test/es6/module-functionality.js +++ b/test/es6/module-functionality.js @@ -291,6 +291,17 @@ var tests = [ WScript.LoadModule(functionBody, 'samethread'); } }, + { + name: "Nested function in module function body which captures exported symbol doesn't create empty frame object", + body: function() { + let functionBody = + `function foo() { }; + export { foo }; + function bar() { foo(); };`; + + WScript.LoadModule(functionBody, 'samethread'); + } + }, ]; testRunner.runTests(tests, { verbose: WScript.Arguments[0] != "summary" });