Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 10 additions & 8 deletions lib/Parser/Hash.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,23 +27,24 @@ 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

// This flag is used by the Parser CountDcls and FillDcls methods.
// 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
Expand Down Expand Up @@ -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()
{
Expand Down Expand Up @@ -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; }
};


Expand Down
21 changes: 6 additions & 15 deletions lib/Parser/Parse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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.
Expand All @@ -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);
Expand Down Expand Up @@ -2142,7 +2133,7 @@ void Parser::ParseNamedImportOrExportClause(ModuleImportOrExportEntryList* impor
}
else
{
MarkIdentifierReferenceIsModuleExport(identifierName);
identifierName->SetIsModuleExport();
AddModuleImportOrExportEntry(importOrExportEntryList, nullptr, identifierName, identifierAs, nullptr);
}
}
Expand Down
11 changes: 11 additions & 0 deletions test/es6/module-functionality.js
Original file line number Diff line number Diff line change
Expand Up @@ -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" });