Skip to content

Commit 6ae6c0a

Browse files
committed
Fix FuncInfoStack to be correct when emitting a function with a split body and param scope
When we emit a function with a split body and param scope, we emit the param scope before we push the FuncInfo into the FuncInfoStack. This means that functions defined in the param scope will see an incorrect FuncInfoStack.
1 parent 106848c commit 6ae6c0a

File tree

5 files changed

+67
-6
lines changed

5 files changed

+67
-6
lines changed

lib/Runtime/ByteCode/ByteCodeEmitter.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3481,8 +3481,6 @@ void ByteCodeGenerator::EmitScopeList(ParseNode *pnode, ParseNode *breakOnBodySc
34813481
}
34823482
this->StartEmitFunction(pnode->AsParseNodeFnc());
34833483

3484-
PushFuncInfo(_u("StartEmitFunction"), funcInfo);
3485-
34863484
if (!funcInfo->IsBodyAndParamScopeMerged())
34873485
{
34883486
this->EmitScopeList(pnode->AsParseNodeFnc()->pnodeBodyScope->pnodeScopes);
@@ -3886,6 +3884,8 @@ void ByteCodeGenerator::StartEmitFunction(ParseNodeFnc *pnodeFnc)
38863884
}
38873885
}
38883886

3887+
PushFuncInfo(_u("StartEmitFunction"), funcInfo);
3888+
38893889
if (!funcInfo->IsBodyAndParamScopeMerged())
38903890
{
38913891
ParseNodeBlock * paramBlock = pnodeFnc->pnodeScopes;

lib/Runtime/ByteCode/ByteCodeGenerator.cpp

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1840,7 +1840,7 @@ FuncInfo *ByteCodeGenerator::FindEnclosingNonLambda()
18401840
return nullptr;
18411841
}
18421842

1843-
FuncInfo* GetParentFuncInfo(FuncInfo* child)
1843+
FuncInfo* ByteCodeGenerator::GetParentFuncInfo(FuncInfo* child)
18441844
{
18451845
for (Scope* scope = child->GetBodyScope(); scope; scope = scope->GetEnclosingScope())
18461846
{
@@ -1853,6 +1853,19 @@ FuncInfo* GetParentFuncInfo(FuncInfo* child)
18531853
return nullptr;
18541854
}
18551855

1856+
FuncInfo* ByteCodeGenerator::GetEnclosingFuncInfo()
1857+
{
1858+
FuncInfo* top = this->funcInfoStack->Pop();
1859+
1860+
Assert(!this->funcInfoStack->Empty());
1861+
1862+
FuncInfo* second = this->funcInfoStack->Top();
1863+
1864+
this->funcInfoStack->Push(top);
1865+
1866+
return second;
1867+
}
1868+
18561869
bool ByteCodeGenerator::CanStackNestedFunc(FuncInfo * funcInfo, bool trace)
18571870
{
18581871
#if ENABLE_DEBUG_CONFIG_OPTIONS
@@ -2634,7 +2647,7 @@ void AssignFuncSymRegister(ParseNodeFnc * pnodeFnc, ByteCodeGenerator * byteCode
26342647
Assert(byteCodeGenerator->GetCurrentScope()->GetFunc() == sym->GetScope()->GetFunc());
26352648
if (byteCodeGenerator->GetCurrentScope()->GetFunc() != sym->GetScope()->GetFunc())
26362649
{
2637-
Assert(GetParentFuncInfo(byteCodeGenerator->GetCurrentScope()->GetFunc()) == sym->GetScope()->GetFunc());
2650+
Assert(ByteCodeGenerator::GetParentFuncInfo(byteCodeGenerator->GetCurrentScope()->GetFunc()) == sym->GetScope()->GetFunc());
26382651
sym->GetScope()->SetMustInstantiate(true);
26392652
byteCodeGenerator->ProcessCapturedSym(sym);
26402653
sym->GetScope()->GetFunc()->SetHasLocalInClosure(true);

lib/Runtime/ByteCode/ByteCodeGenerator.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -402,6 +402,8 @@ class ByteCodeGenerator
402402
void PopulateFormalsScope(uint beginOffset, FuncInfo *funcInfo, ParseNodeFnc *pnodeFnc);
403403
void InsertPropertyToDebuggerScope(FuncInfo* funcInfo, Js::DebuggerScope* debuggerScope, Symbol* sym);
404404
FuncInfo *FindEnclosingNonLambda();
405+
static FuncInfo* GetParentFuncInfo(FuncInfo* child);
406+
FuncInfo* GetEnclosingFuncInfo();
405407

406408
bool CanStackNestedFunc(FuncInfo * funcInfo, bool trace = false);
407409
void CheckDeferParseHasMaybeEscapedNestedFunc();

lib/Runtime/ByteCode/ScopeInfo.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ namespace Js
166166
Assert(currentScope->GetScopeType() == ScopeType_FunctionBody);
167167
Assert(currentScope->GetEnclosingScope());
168168

169-
FuncInfo* func = currentScope->GetEnclosingScope()->GetFunc();
169+
FuncInfo* func = byteCodeGenerator->GetEnclosingFuncInfo();
170170
Assert(func);
171171

172172
if (func->IsBodyAndParamScopeMerged() && !(func->funcExprScope && func->funcExprScope->GetCanMerge()))

test/Bugs/bug_OS18926499.js

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ try {
2424
console.log('pass');
2525
}
2626

27-
var foo3 = function foo3a(a = (function foo3b() { foo3a; })()) {
27+
var foo3 = function foo3a(a = (function foo3b() { +foo3a; })()) {
2828
a;
2929
};
3030

@@ -46,3 +46,49 @@ try {
4646
} catch {
4747
console.log('pass');
4848
}
49+
50+
var foo5 = function foo5a(a = (function(){(function(b = 123) { +x; })()})()) {
51+
function bar() { eval(''); }
52+
var x;
53+
};
54+
55+
try {
56+
foo5();
57+
console.log('fail');
58+
} catch {
59+
console.log('pass');
60+
}
61+
62+
function foo6(a, b = (function() {a; +x;})()) {
63+
function bar() { eval(''); }
64+
var x;
65+
};
66+
67+
try {
68+
foo6();
69+
console.log('fail');
70+
} catch {
71+
console.log('pass');
72+
}
73+
74+
var foo8 = function foo8a(b, a = (function foo8b() { console.log(x); })()) {
75+
a;
76+
var x = 'fail';
77+
};
78+
79+
try {
80+
foo8()
81+
console.log('fail');
82+
} catch {
83+
console.log('pass');
84+
}
85+
86+
var foo9 = function foo9a(b = 'pass', a = (function foo9b() { console.log(b); })()) {
87+
};
88+
89+
try {
90+
foo9()
91+
console.log('pass');
92+
} catch {
93+
console.log('fail');
94+
}

0 commit comments

Comments
 (0)