@@ -3278,9 +3278,9 @@ void ByteCodeGenerator::EmitOneFunction(ParseNode *pnode)
32783278 {
32793279 // Emit bytecode to copy the initial values from param names to their corresponding body bindings.
32803280 // We have to do this after the rest param is marked as false for need declaration.
3281- paramScope->ForEachSymbol ([this , funcInfo, paramScope, byteCodeFunction ](Symbol* param) {
3281+ paramScope->ForEachSymbol ([& ](Symbol* param) {
32823282 Symbol* varSym = funcInfo->GetBodyScope ()->FindLocalSymbol (param->GetName ());
3283- Assert (varSym || param->GetIsArguments ());
3283+ Assert (varSym || param->GetIsArguments () || pnode-> sxFnc . pnodeName -> sxVar . sym == param );
32843284 Assert (param->GetIsArguments () || param->IsInSlot (funcInfo));
32853285 if (varSym && varSym->GetSymbolType () == STVariable && (varSym->IsInSlot (funcInfo) || varSym->GetLocation () != Js::Constants::NoRegister))
32863286 {
@@ -3570,22 +3570,7 @@ void ByteCodeGenerator::EmitScopeList(ParseNode *pnode, ParseNode *breakOnBodySc
35703570 this ->StartEmitFunction (pnode);
35713571
35723572 Scope* paramScope = pnode->sxFnc .funcInfo ->GetParamScope ();
3573- Scope* bodyScope = pnode->sxFnc .funcInfo ->GetBodyScope ();
35743573
3575- if (paramScope && !paramScope->GetCanMergeWithBodyScope ())
3576- {
3577- ParseNodePtr paramBlock = pnode->sxFnc .pnodeScopes ;
3578- Assert (paramBlock->nop == knopBlock && paramBlock->sxBlock .blockType == Parameter);
3579-
3580- PushScope (paramScope);
3581-
3582- // While emitting the functions we have to stop when we see the body scope block.
3583- // Otherwise functions defined in the body scope will not be able to get the right references.
3584- this ->EmitScopeList (paramBlock->sxBlock .pnodeScopes , pnode->sxFnc .pnodeBodyScope );
3585- Assert (this ->GetCurrentScope () == paramScope);
3586- }
3587-
3588- PushScope (bodyScope);
35893574 // Persist outer func scope info if nested func is deferred
35903575 if (CONFIG_FLAG (DeferNested))
35913576 {
@@ -3605,12 +3590,6 @@ void ByteCodeGenerator::EmitScopeList(ParseNode *pnode, ParseNode *breakOnBodySc
36053590
36063591 this ->EmitOneFunction (pnode);
36073592 this ->EndEmitFunction (pnode);
3608-
3609- if (paramScope && !paramScope->GetCanMergeWithBodyScope ())
3610- {
3611- Assert (this ->GetCurrentScope () == paramScope);
3612- PopScope (); // Pop the param scope
3613- }
36143593 }
36153594 pnode = pnode->sxFnc .pnodeNext ;
36163595 break ;
@@ -3768,7 +3747,14 @@ void ByteCodeGenerator::StartEmitFunction(ParseNode *pnodeFnc)
37683747 else
37693748 {
37703749 Symbol *sym = funcInfo->root ->sxFnc .GetFuncSymbol ();
3771- funcInfo->bodyScope ->AddSymbol (sym);
3750+ if (funcInfo->paramScope ->GetCanMergeWithBodyScope ())
3751+ {
3752+ funcInfo->bodyScope ->AddSymbol (sym);
3753+ }
3754+ else
3755+ {
3756+ funcInfo->paramScope ->AddSymbol (sym);
3757+ }
37723758 }
37733759 }
37743760
@@ -3803,9 +3789,6 @@ void ByteCodeGenerator::StartEmitFunction(ParseNode *pnodeFnc)
38033789 }
38043790 }
38053791
3806- bodyScope->SetMustInstantiate (funcInfo->frameObjRegister != Js::Constants::NoRegister || funcInfo->frameSlotsRegister != Js::Constants::NoRegister);
3807- paramScope->SetMustInstantiate (!paramScope->GetCanMergeWithBodyScope ());
3808-
38093792 if (bodyScope->GetIsObject ())
38103793 {
38113794 // Win8 908700: Disable under F12 debugger because there are too many cached scopes holding onto locals.
@@ -4016,6 +3999,18 @@ void ByteCodeGenerator::StartEmitFunction(ParseNode *pnodeFnc)
40163999 this ->EnsureLetConstScopeSlots (pnodeFnc->sxFnc .pnodeBodyScope , funcInfo);
40174000 }
40184001 }
4002+
4003+ if (!paramScope->GetCanMergeWithBodyScope () && bodyScope->GetScopeSlotCount () == 0 && !bodyScope->GetHasOwnLocalInClosure ())
4004+ {
4005+ // When we have split scope the body scope may be wrongly marked as must instantiate even though the capture occurred
4006+ // in param scope. This check is to make sure if no capture occurs in body scope make in not must instantiate.
4007+ bodyScope->SetMustInstantiate (false );
4008+ }
4009+ else
4010+ {
4011+ bodyScope->SetMustInstantiate (funcInfo->frameObjRegister != Js::Constants::NoRegister || funcInfo->frameSlotsRegister != Js::Constants::NoRegister);
4012+ }
4013+ paramScope->SetMustInstantiate (!paramScope->GetCanMergeWithBodyScope ());
40194014 }
40204015 else
40214016 {
@@ -4026,6 +4021,21 @@ void ByteCodeGenerator::StartEmitFunction(ParseNode *pnodeFnc)
40264021 Assert (bodyScope->GetIsObject ());
40274022 }
40284023 }
4024+
4025+ if (paramScope && !paramScope->GetCanMergeWithBodyScope ())
4026+ {
4027+ ParseNodePtr paramBlock = pnodeFnc->sxFnc .pnodeScopes ;
4028+ Assert (paramBlock->nop == knopBlock && paramBlock->sxBlock .blockType == Parameter);
4029+
4030+ PushScope (paramScope);
4031+
4032+ // While emitting the functions we have to stop when we see the body scope block.
4033+ // Otherwise functions defined in the body scope will not be able to get the right references.
4034+ this ->EmitScopeList (paramBlock->sxBlock .pnodeScopes , pnodeFnc->sxFnc .pnodeBodyScope );
4035+ Assert (this ->GetCurrentScope () == paramScope);
4036+ }
4037+
4038+ PushScope (bodyScope);
40294039}
40304040
40314041void ByteCodeGenerator::EmitModuleExportAccess (Symbol* sym, Js::OpCode opcode, Js::RegSlot location, FuncInfo* funcInfo)
@@ -4151,6 +4161,13 @@ void ByteCodeGenerator::EndEmitFunction(ParseNode *pnodeFnc)
41514161
41524162 FuncInfo *funcInfo = pnodeFnc->sxFnc .funcInfo ;
41534163
4164+ Scope* paramScope = funcInfo->paramScope ;
4165+ if (paramScope && !paramScope->GetCanMergeWithBodyScope ())
4166+ {
4167+ Assert (this ->GetCurrentScope () == paramScope);
4168+ PopScope (); // Pop the param scope
4169+ }
4170+
41544171 Scope *scope = funcInfo->funcExprScope ;
41554172 if (scope && scope->GetMustInstantiate ())
41564173 {
0 commit comments