Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
pleath committed Jun 10, 2019
1 parent 90f67af commit 06a1438
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 19 deletions.
14 changes: 0 additions & 14 deletions lib/Parser/Parse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5444,20 +5444,6 @@ void Parser::ParseFncDeclHelper(ParseNodeFnc * pnodeFnc, LPCOLESTR pNameHint, us
}
return false;
});

if (pnodeFnc->IsBodyAndParamScopeMerged() && !fDeclaration && pnodeFnc->pnodeName != nullptr)
{
Assert(pnodeFnc->pnodeName->nop == knopVarDecl);
Symbol* funcSym = pnodeFnc->pnodeName->sym;
if (funcSym->GetPid()->GetTopRef()->GetFuncScopeId() > pnodeFnc->functionId)
{
// This is a function expression with name captured in the param scope. In non-eval, non-split cases the function
// name symbol is added to the body scope to make it accessible in the body. But if there is a function or var
// declaration with the same name in the body then adding to the body will fail. So in this case we have to add
// the name symbol to the param scope by splitting it.
pnodeFnc->ResetBodyAndParamScopeMerged();
}
}
}
}

Expand Down
11 changes: 11 additions & 0 deletions lib/Runtime/ByteCode/ByteCodeGenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3091,6 +3091,17 @@ void ByteCodeGenerator::ProcessCapturedSym(Symbol *sym)

Assert(sym->NeedsSlotAlloc(this, funcHome) || sym->GetIsGlobal() || sym->GetIsModuleImport() || sym->GetIsModuleExportStorage());

if (sym->GetScope()->GetScopeType() == ScopeType_FuncExpr)
{
if ((funcHome->GetParamScope() && Scope::HasSymbolName(funcHome->GetParamScope(), sym->GetName())) ||
(funcHome->IsBodyAndParamScopeMerged() && funcHome->GetBodyScope() && Scope::HasSymbolName(funcHome->GetBodyScope(), sym->GetName())))
{
// Make sure the function expression scope gets instantiated, since we can't merge the name symbol into another scope.
// Make it an object, since that's the only case the code gen can currently handle.
sym->GetScope()->SetIsObject();
}
}

// If this is not a local property, or not all its references can be tracked, or
// it's not scoped to the function, or we're in debug mode, disable the delayed capture optimization.
if (funcHome->IsGlobalFunction() ||
Expand Down
20 changes: 15 additions & 5 deletions lib/Runtime/ByteCode/Scope.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,19 +110,28 @@ class Scope
}
}

static bool HasSymbolName(Scope * scope, const JsUtil::CharacterBuffer<WCHAR>& name)
{
for (Symbol *sym = scope->m_symList; sym; sym = sym->GetNext())
{
if (sym->GetName() == name)
{
return true;
}
}
return false;
}

void AddSymbol(Symbol *sym)
{
if (enclosingScope == nullptr)
{
sym->SetIsGlobal(true);
}
sym->SetScope(this);
for (Symbol *symInList = m_symList; symInList; symInList = symInList->GetNext())
if (HasSymbolName(this, sym->GetName()))
{
if (symInList->GetName() == sym->GetName())
{
return;
}
return;
}
sym->SetNext(m_symList);
m_symList = sym;
Expand All @@ -136,6 +145,7 @@ class Scope
sym->SetIsGlobal(true);
}
sym->SetScope(this);
Assert(!HasSymbolName(this, sym->GetName()));
sym->SetNext(m_symList);
m_symList = sym;
m_count++;
Expand Down

0 comments on commit 06a1438

Please sign in to comment.