Skip to content

Commit 36ce60b

Browse files
committed
Undo defer parse mode issue with formals
In undo defer parse mode we reconstruct the pid ref stack for the formals. With my last change to insert a new reference for each param symbol in the body I missed making change in the undo defer parse mode. This change adds the code to do that for both split scope and non-split scope.
1 parent f03bda5 commit 36ce60b

3 files changed

Lines changed: 94 additions & 2 deletions

File tree

lib/Parser/Parse.cpp

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5032,9 +5032,8 @@ bool Parser::ParseFncDeclHelper(ParseNodePtr pnodeFnc, ParseNodePtr pnodeFncPare
50325032
{
50335033
paramScope->ForEachSymbol([this](Symbol* paramSym)
50345034
{
5035-
Symbol* sym = paramSym->GetPid()->GetTopRef()->GetSym();
50365035
PidRefStack* ref = PushPidRef(paramSym->GetPid());
5037-
ref->SetSym(sym);
5036+
ref->SetSym(paramSym);
50385037
});
50395038
}
50405039

@@ -10470,6 +10469,29 @@ void Parser::FinishDeferredFunction(ParseNodePtr pnodeScopeList)
1047010469
pnodeFnc->sxFnc.pnodeVars = nullptr;
1047110470
m_ppnodeVar = &pnodeFnc->sxFnc.pnodeVars;
1047210471

10472+
if (scope != nullptr && !pnodeFnc->sxFnc.IsAsync())
10473+
{
10474+
if (scope->GetCanMergeWithBodyScope())
10475+
{
10476+
scope->ForEachSymbol([this](Symbol* paramSym)
10477+
{
10478+
PidRefStack* ref = PushPidRef(paramSym->GetPid());
10479+
ref->SetSym(paramSym);
10480+
});
10481+
}
10482+
else
10483+
{
10484+
OUTPUT_TRACE_DEBUGONLY(Js::ParsePhase, _u("The param and body scope of the function %s cannot be merged\n"), pnodeFnc->sxFnc.pnodeName ? pnodeFnc->sxFnc.pnodeName->sxVar.pid->Psz() : _u("Anonymous function"));
10485+
// Add a new symbol reference for each formal in the param scope to the body scope.
10486+
scope->ForEachSymbol([this](Symbol* param) {
10487+
OUTPUT_TRACE_DEBUGONLY(Js::ParsePhase, _u("Creating a duplicate symbol for the parameter %s in the body scope\n"), param->GetPid()->Psz());
10488+
ParseNodePtr paramNode = this->CreateVarDeclNode(param->GetPid(), STVariable, false, nullptr, false);
10489+
Assert(paramNode && paramNode->sxVar.sym->GetScope()->GetScopeType() == ScopeType_FunctionBody);
10490+
paramNode->sxVar.sym->SetHasInit(true);
10491+
});
10492+
}
10493+
}
10494+
1047310495
Assert(m_currentNodeNonLambdaFunc == nullptr);
1047410496
m_currentNodeNonLambdaFunc = pnodeFnc;
1047510497

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
//-------------------------------------------------------------------------------------------------------
2+
// Copyright (C) Microsoft. All rights reserved.
3+
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
4+
//-------------------------------------------------------------------------------------------------------
5+
6+
function foo1(a, b) {
7+
if (b != 10) {
8+
print("FAILED")
9+
} else {
10+
print("PASSED");
11+
}
12+
if (eval('b') != 10) {
13+
print("FAILED")
14+
} else {
15+
print("PASSED");
16+
}
17+
var b = 1;
18+
if (b != 1) {
19+
print("FAILED")
20+
} else {
21+
print("PASSED");
22+
}
23+
}
24+
foo1(undefined, 10);
25+
26+
function foo2(a, b = 10) {
27+
if (b != 10) {
28+
print("FAILED")
29+
} else {
30+
print("PASSED");
31+
}
32+
if (eval('b') != 10) {
33+
print("FAILED")
34+
} else {
35+
print("PASSED");
36+
}
37+
var b = 1;
38+
if (b != 1) {
39+
print("FAILED")
40+
} else {
41+
print("PASSED");
42+
}
43+
}
44+
foo2();
45+
46+
function foo3(a = 10, b = function () { return a; }) {
47+
if (b() != 10) {
48+
print("FAILED")
49+
} else {
50+
print("PASSED");
51+
}
52+
if (eval('b()') != 10) {
53+
print("FAILED")
54+
} else {
55+
print("PASSED");
56+
}
57+
var a = 1;
58+
if (b() != 10) {
59+
print("FAILED")
60+
} else {
61+
print("PASSED");
62+
}
63+
}
64+
foo3();

test/es6/rlexe.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -730,6 +730,12 @@
730730
<compile-flags>-force:deferparse -ES6DefaultArgsSplitScope -ES6Generators -args summary -endargs</compile-flags>
731731
</default>
732732
</test>
733+
<test>
734+
<default>
735+
<files>default-splitscope-undodeferparse.js</files>
736+
<compile-flags>-forceundodefer -ES6DefaultArgsSplitScope</compile-flags>
737+
</default>
738+
</test>
733739
<test>
734740
<default>
735741
<files>rest.js</files>

0 commit comments

Comments
 (0)