You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Fix for the pid ref issues with default parameters
When param and body scopes are merged, when a formal is referenced in the
body we were using an additional argument named maxScopeId to look up
until the param scope block. This logic was causing issues when we try to
insert new references into the pid ref linked list. This changelist gets
rid of the requirement of maxScopeId by adding additional pid refs for
each param scope symbol into the body before we start parsing the body.
// One of the symbol has non local reference. Mark the param scope as we can't merge it with body scope.
5068
-
paramScope->SetCannotMergeWithBodyScope();
5069
-
returntrue;
5070
-
}
5071
-
else
5072
-
{
5073
-
// If no non-local references are there then the top of the ref stack should point to the same symbol.
5074
-
Assert(sym->GetPid()->GetTopRef()->sym == sym);
5075
-
}
5076
-
returnfalse;
5077
-
});
5078
-
}
5079
-
5080
-
if (!paramScope->GetCanMergeWithBodyScope())
5081
-
{
5082
-
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"));
5083
-
// Add a new symbol reference for each formal in the param scope to the body scope.
5084
-
paramScope->ForEachSymbol([this](Symbol* param) {
5085
-
OUTPUT_TRACE_DEBUGONLY(Js::ParsePhase, _u("Creating a duplicate symbol for the parameter %s in the body scope\n"), param->GetPid()->Psz());
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"));
5086
+
// Add a new symbol reference for each formal in the param scope to the body scope.
5087
+
paramScope->ForEachSymbol([this](Symbol* param) {
5088
+
OUTPUT_TRACE_DEBUGONLY(Js::ParsePhase, _u("Creating a duplicate symbol for the parameter %s in the body scope\n"), param->GetPid()->Psz());
Copy file name to clipboardExpand all lines: test/es6/default-splitscope.js
+67-2Lines changed: 67 additions & 2 deletions
Original file line number
Diff line number
Diff line change
@@ -57,7 +57,7 @@ var tests = [
57
57
assert.areEqual(10,f5()()(),"Parameter scope works fine with nested functions");
58
58
59
59
vara1=10;
60
-
functionf6(b=function(){returna1;}){
60
+
functionf6(a,b=function(){a;returna1;}){
61
61
assert.areEqual(undefined,a1,"Inside the function body the assignment hasn't happened yet");
62
62
vara1=20;
63
63
assert.areEqual(20,a1,"Assignment to the symbol inside the function changes the value");
@@ -69,7 +69,7 @@ var tests = [
69
69
a=20;
70
70
returnb;
71
71
}
72
-
assert.areEqual(10,f7().iFnc(),"Function definition inside the object literal should capture the formal from the param scope");
72
+
assert.areEqual(10,f7().iFnc(),"Function definition inside the object literal should capture the formal from the param scope");
73
73
}
74
74
},
75
75
{
@@ -505,6 +505,71 @@ var tests = [
505
505
assert.areEqual(11,f9()()()(),"Split scope function defined within the param scope should capture the formals from the corresponding param scope in nested scope");
506
506
}
507
507
},
508
+
{
509
+
name: "Split scope with symbol overriding",
510
+
body: function(){
511
+
functionf1(a=10,b=function(){returna;}){
512
+
assert.areEqual(100,a(),"Function definition inside the body is hoisted");
513
+
functiona(){
514
+
return100;
515
+
}
516
+
returnb;
517
+
}
518
+
assert.areEqual(10,f1()(),"Function definition in the param scope captures the symbol from the param scope");
519
+
520
+
functionf2(a=10,b=function(){returna;},c=b){
521
+
a=20;
522
+
assert.areEqual(20,b(),"Function definition in the body scope captures the body symbol");
523
+
functionb(){
524
+
returna;
525
+
}
526
+
return[c,b];
527
+
}
528
+
varresult=f2();
529
+
assert.areEqual(10,result[0](),"Function definition in the param scope captures the param scope symbol");
530
+
assert.areEqual(20,result[1](),"Function definition in the body captures the body symbol");
531
+
532
+
varg=1;
533
+
functionf3(a=10,b=function(){a;returng;}){
534
+
assert.areEqual(10,g(),"Function definition inside the body is unaffected by the outer variable");
535
+
functiong(){
536
+
return10;
537
+
}
538
+
returnb;
539
+
}
540
+
assert.areEqual(1,f3()(),"Function definition in the param scope captures the outer scoped var");
541
+
542
+
functionf4(a=x1,b=functiong(){
543
+
a;
544
+
returnfunctionh(){
545
+
assert.areEqual(10,x1,"x1 is captured from the outer scope");
546
+
};
547
+
}){
548
+
varx1=100;
549
+
b()();
550
+
};
551
+
varx1=10;
552
+
f4();
553
+
554
+
varx2=1;
555
+
functionf5(a=x2,b=function(){a;returnx2;}){
556
+
{
557
+
functionx2(){
558
+
}
559
+
}
560
+
varx2=2;
561
+
returnb;
562
+
}
563
+
assert.areEqual(1,f5()(),"Symbol capture at the param scope is unaffected by the inner definitions");
564
+
565
+
varx3=1;
566
+
functionf6(a=x3,b=function(_x){a;returnx3;}){
567
+
varx3=2;
568
+
returnb;
569
+
}
570
+
assert.areEqual(1,f6()(),"Symbol capture at the param scope is unaffected by other references in the body and param");
0 commit comments