Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
boingoing authored and pleath committed Mar 6, 2020
1 parent e6abd1d commit d969210
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 12 deletions.
4 changes: 2 additions & 2 deletions lib/Parser/Parse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1744,9 +1744,9 @@ void Parser::BindPidRefsInScope(IdentPtr pid, Symbol *sym, int blockId, uint max
Assert(funcExprScope->GetScopeType() == ScopeType_FuncExpr);

ParseNodeBlock* bodyScope = m_currentNodeFunc->pnodeBodyScope;
Assert(bodyScope->blockType == PnodeBlockType::Function);
Assert(bodyScope == nullptr || bodyScope->blockType == PnodeBlockType::Function);

if (ref->GetScopeId() < bodyScope->blockId && ref->GetScopeId() > blockId)
if (bodyScope && ref->GetScopeId() < bodyScope->blockId && ref->GetScopeId() > blockId)
{
funcExprScope->SetIsObject();
}
Expand Down
19 changes: 10 additions & 9 deletions lib/Runtime/ByteCode/ByteCodeEmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2226,7 +2226,7 @@ void ByteCodeGenerator::LoadSuperObject(FuncInfo *funcInfo)
m_writer.Reg1(Js::OpCode::LdHomeObj, superSym->GetLocation());
}

void ByteCodeGenerator::EmitSuperCall(FuncInfo* funcInfo, ParseNodeSuperCall * pnodeSuperCall, BOOL fReturnValue)
void ByteCodeGenerator::EmitSuperCall(FuncInfo* funcInfo, ParseNodeSuperCall * pnodeSuperCall, BOOL fReturnValue, BOOL fEvaluateComponents)
{
FuncInfo* nonLambdaFunc = funcInfo;
bool isResultUsed = pnodeSuperCall->isUsed;
Expand Down Expand Up @@ -2292,7 +2292,7 @@ void ByteCodeGenerator::EmitSuperCall(FuncInfo* funcInfo, ParseNodeSuperCall * p
this->Writer()->MarkLabel(useNewTargetForThisLabel);
this->Writer()->Reg2(Js::OpCode::Ld_A, thisForSuperCall, pnodeSuperCall->pnodeNewTarget->location);
this->Writer()->MarkLabel(makeCallLabel);
EmitCall(pnodeSuperCall, this, funcInfo, fReturnValue, /*fEvaluateComponents*/ true, thisForSuperCall, pnodeSuperCall->pnodeNewTarget->location);
EmitCall(pnodeSuperCall, this, funcInfo, fReturnValue, fEvaluateComponents, thisForSuperCall, pnodeSuperCall->pnodeNewTarget->location);

// We have to use another temp for the this value before assigning to this register.
// This is because IRBuilder does not expect us to use the value of a temp after potentially assigning to that same temp.
Expand Down Expand Up @@ -6969,7 +6969,7 @@ void EmitLoad(
{
funcInfo->AcquireLoc(pnodeCallLhs);
EmitReference(pnodeCallLhs, byteCodeGenerator, funcInfo);
byteCodeGenerator->EmitSuperCall(funcInfo, pnodeCallLhs->AsParseNodeSuperCall(), /*fReturnValue=*/ false);
byteCodeGenerator->EmitSuperCall(funcInfo, pnodeCallLhs->AsParseNodeSuperCall(), /*fReturnValue=*/ false, /*fEvaluateComponents=*/ false);
}
else if (pnodeCallLhs->pnodeTarget->nop == knopImport)
{
Expand Down Expand Up @@ -7890,6 +7890,7 @@ void EmitCallI(
void EmitCallInstrNoEvalComponents(
ParseNodeCall *pnodeCall,
BOOL fIsEval,
BOOL fHasNewTarget,
Js::RegSlot thisLocation,
Js::RegSlot callObjLocation,
uint32 actualArgCount,
Expand All @@ -7913,14 +7914,14 @@ void EmitCallInstrNoEvalComponents(
Js::PropertyId propertyId = pnodeTarget->AsParseNodeBin()->pnode2->AsParseNodeName()->PropertyIdFromNameNode();

EmitMethodFld(pnodeTarget, callObjLocation, propertyId, byteCodeGenerator, funcInfo);
EmitCallI(pnodeCall, /*fEvaluateComponents*/ FALSE, fIsEval, /*fHasNewTarget*/ FALSE, actualArgCount, byteCodeGenerator, funcInfo, callSiteId, spreadIndices);
EmitCallI(pnodeCall, /*fEvaluateComponents*/ FALSE, fIsEval, fHasNewTarget, actualArgCount, byteCodeGenerator, funcInfo, callSiteId, spreadIndices);
}
break;

case knopIndex:
{
EmitMethodElem(pnodeTarget, pnodeTarget->AsParseNodeBin()->pnode1->location, pnodeTarget->AsParseNodeBin()->pnode2->location, byteCodeGenerator);
EmitCallI(pnodeCall, /*fEvaluateComponents*/ FALSE, fIsEval, /*fHasNewTarget*/ FALSE, actualArgCount, byteCodeGenerator, funcInfo, callSiteId, spreadIndices);
EmitCallI(pnodeCall, /*fEvaluateComponents*/ FALSE, fIsEval, fHasNewTarget, actualArgCount, byteCodeGenerator, funcInfo, callSiteId, spreadIndices);
}
break;

Expand All @@ -7937,14 +7938,14 @@ void EmitCallInstrNoEvalComponents(

Js::PropertyId propertyId = pnodeTarget->AsParseNodeName()->PropertyIdFromNameNode();
EmitMethodFld(pnodeTarget, callObjLocation, propertyId, byteCodeGenerator, funcInfo);
EmitCallI(pnodeCall, /*fEvaluateComponents*/ FALSE, fIsEval, /*fHasNewTarget*/ FALSE, actualArgCount, byteCodeGenerator, funcInfo, callSiteId, spreadIndices);
EmitCallI(pnodeCall, /*fEvaluateComponents*/ FALSE, fIsEval, fHasNewTarget, actualArgCount, byteCodeGenerator, funcInfo, callSiteId, spreadIndices);
break;
}
}
// FALL THROUGH

default:
EmitCallI(pnodeCall, /*fEvaluateComponents*/ FALSE, fIsEval, /*fHasNewTarget*/ FALSE, actualArgCount, byteCodeGenerator, funcInfo, callSiteId, spreadIndices);
EmitCallI(pnodeCall, /*fEvaluateComponents*/ FALSE, fIsEval, fHasNewTarget, actualArgCount, byteCodeGenerator, funcInfo, callSiteId, spreadIndices);
break;
}
}
Expand Down Expand Up @@ -8183,7 +8184,7 @@ void EmitCall(

if (!fEvaluateComponents)
{
EmitCallInstrNoEvalComponents(pnodeCall, fIsEval, thisLocation, callObjLocation, argSlotCount, byteCodeGenerator, funcInfo, callSiteId, spreadIndices);
EmitCallInstrNoEvalComponents(pnodeCall, fIsEval, fHasNewTarget, thisLocation, callObjLocation, argSlotCount, byteCodeGenerator, funcInfo, callSiteId, spreadIndices);
}
else
{
Expand Down Expand Up @@ -10548,7 +10549,7 @@ void Emit(ParseNode *pnode, ByteCodeGenerator *byteCodeGenerator, FuncInfo *func

if (pnodeCall->isSuperCall)
{
byteCodeGenerator->EmitSuperCall(funcInfo, pnodeCall->AsParseNodeSuperCall(), fReturnValue);
byteCodeGenerator->EmitSuperCall(funcInfo, pnodeCall->AsParseNodeSuperCall(), fReturnValue, /*fEvaluateComponents=*/ true);
}
else if (pnodeCall->pnodeTarget->nop == knopImport)
{
Expand Down
2 changes: 1 addition & 1 deletion lib/Runtime/ByteCode/ByteCodeGenerator.h
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,7 @@ class ByteCodeGenerator
void LoadNewTargetObject(FuncInfo *funcInfo);
void LoadSuperObject(FuncInfo *funcInfo);
void LoadSuperConstructorObject(FuncInfo *funcInfo);
void EmitSuperCall(FuncInfo* funcInfo, ParseNodeSuperCall * pnodeSuperCall, BOOL fReturnValue);
void EmitSuperCall(FuncInfo* funcInfo, ParseNodeSuperCall * pnodeSuperCall, BOOL fReturnValue, BOOL fEvaluateComponents);
void EmitClassConstructorEndCode(FuncInfo *funcInfo);

// TODO: home the 'this' argument
Expand Down
24 changes: 24 additions & 0 deletions test/Bugs/bug_6239.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
//-------------------------------------------------------------------------------------------------------
// Copyright (C) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
//-------------------------------------------------------------------------------------------------------

// force:deferparse

(function v2(a = function v2(){ +v2; }) {
a();
console.log('pass');
})();

(function v2(a = function v3(){ function v4(b = (function v4() {v4; console.log('pass');})()){}; v4(); }) {
a();
console.log('pass');
})();

(function a() {
a = function a(a=function(a){}){}
function a(){
var a = "a";
}
console.log('pass');
})();
6 changes: 6 additions & 0 deletions test/Bugs/rlexe.xml
Original file line number Diff line number Diff line change
Expand Up @@ -548,4 +548,10 @@
<compile-flags>-force:deferparse</compile-flags>
</default>
</test>
<test>
<default>
<files>bug_6239.js</files>
<compile-flags>-force:deferparse</compile-flags>
</default>
</test>
</regress-exe>

0 comments on commit d969210

Please sign in to comment.