@@ -7925,10 +7925,14 @@ Js::ArgSlot EmitNewObjectOfConstants(
7925
7925
return actualArgCount;
7926
7926
}
7927
7927
7928
- void EmitMethodFld (bool isRoot, bool isScoped, Js::RegSlot location, Js::RegSlot callObjLocation, Js::PropertyId propertyId, ByteCodeGenerator *byteCodeGenerator, FuncInfo *funcInfo, bool registerCacheIdForCall = true )
7928
+ void EmitMethodFld (bool isRoot, bool isScoped, bool isNullPropagating, Js::RegSlot location, Js::RegSlot callObjLocation, Js::PropertyId propertyId, ByteCodeGenerator *byteCodeGenerator, FuncInfo *funcInfo, bool registerCacheIdForCall = true )
7929
7929
{
7930
7930
Js::OpCode opcode;
7931
- if (!isRoot)
7931
+ if (isNullPropagating)
7932
+ {
7933
+ opcode = (!isScoped && isRoot) ? Js::OpCode::LdRootFld : Js::OpCode::LdFld;
7934
+ }
7935
+ else if (!isRoot)
7932
7936
{
7933
7937
if (callObjLocation == funcInfo->frameObjRegister )
7934
7938
{
@@ -7968,15 +7972,15 @@ void EmitMethodFld(bool isRoot, bool isScoped, Js::RegSlot location, Js::RegSlot
7968
7972
}
7969
7973
}
7970
7974
7971
- void EmitMethodFld (ParseNode *pnode, Js::RegSlot callObjLocation, Js::PropertyId propertyId, ByteCodeGenerator *byteCodeGenerator, FuncInfo *funcInfo, bool registerCacheIdForCall = true )
7975
+ void EmitMethodFld (ParseNodeCall *pnodeCall, ParseNode *pnode, Js::RegSlot callObjLocation, Js::PropertyId propertyId, ByteCodeGenerator *byteCodeGenerator, FuncInfo *funcInfo, bool registerCacheIdForCall = true )
7972
7976
{
7973
7977
// Load a call target of the form x.y(). (Call target may be a plain knopName if we're getting it from
7974
7978
// the global object, etc.)
7975
7979
bool isRoot = pnode->nop == knopName && (pnode->AsParseNodeName ()->sym == nullptr || pnode->AsParseNodeName ()->sym ->GetIsGlobal ());
7976
7980
bool isScoped = (byteCodeGenerator->GetFlags () & fscrEval) != 0 ||
7977
7981
(isRoot && callObjLocation != ByteCodeGenerator::RootObjectRegister);
7978
7982
7979
- EmitMethodFld (isRoot, isScoped, pnode->location , callObjLocation, propertyId, byteCodeGenerator, funcInfo, registerCacheIdForCall);
7983
+ EmitMethodFld (isRoot, isScoped, pnodeCall-> isNullPropagating , pnode->location , callObjLocation, propertyId, byteCodeGenerator, funcInfo, registerCacheIdForCall);
7980
7984
}
7981
7985
7982
7986
// lhs.apply(this, arguments);
@@ -8003,7 +8007,7 @@ void EmitApplyCall(ParseNodeCall* pnodeCall, ByteCodeGenerator* byteCodeGenerato
8003
8007
// call for apply, we won't remove the entry for "apply" cacheId from
8004
8008
// ByteCodeWriter::callRegToLdFldCacheIndexMap, which is contrary to our assumption that we would
8005
8009
// have removed an entry from a map upon seeing its corresponding call.
8006
- EmitMethodFld (applyNode, funcNode->location , propertyId, byteCodeGenerator, funcInfo, false /* registerCacheIdForCall*/ );
8010
+ EmitMethodFld (pnodeCall, applyNode, funcNode->location , propertyId, byteCodeGenerator, funcInfo, false /* registerCacheIdForCall*/ );
8007
8011
8008
8012
Symbol *argSym = funcInfo->GetArgumentsSymbol ();
8009
8013
Assert (argSym && argSym->IsArguments ());
@@ -8106,6 +8110,7 @@ void EmitCallTargetNoEvalComponents(
8106
8110
}
8107
8111
8108
8112
void EmitCallTarget (
8113
+ ParseNodeCall *pnodeCall,
8109
8114
ParseNode *pnodeTarget,
8110
8115
BOOL fSideEffectArgs ,
8111
8116
Js::RegSlot *thisLocation,
@@ -8130,7 +8135,7 @@ void EmitCallTarget(
8130
8135
{
8131
8136
case knopOptChain: {
8132
8137
EmitOptionalChainWrapper (pnodeTarget->AsParseNodeUni (), byteCodeGenerator, funcInfo, [&](ParseNodePtr innerNode) {
8133
- EmitCallTarget (innerNode, fSideEffectArgs , thisLocation, releaseThisLocation, callObjLocation, byteCodeGenerator, funcInfo, callApplyCallSiteId);
8138
+ EmitCallTarget (pnodeCall, innerNode, fSideEffectArgs , thisLocation, releaseThisLocation, callObjLocation, byteCodeGenerator, funcInfo, callApplyCallSiteId);
8134
8139
});
8135
8140
break ;
8136
8141
}
@@ -8179,7 +8184,7 @@ void EmitCallTarget(
8179
8184
{
8180
8185
*thisLocation = pnodeBinTarget->pnode1 ->location ;
8181
8186
EmitNullPropagation (pnodeBinTarget->pnode1 ->location , byteCodeGenerator, funcInfo, pnodeBinTarget->isNullPropagating );
8182
- EmitMethodFld (pnodeBinTarget, protoLocation, propertyId, byteCodeGenerator, funcInfo);
8187
+ EmitMethodFld (pnodeCall, pnodeBinTarget, protoLocation, propertyId, byteCodeGenerator, funcInfo);
8183
8188
}
8184
8189
8185
8190
break ;
@@ -8247,7 +8252,7 @@ void EmitCallTarget(
8247
8252
{
8248
8253
// Load the call target as a property of the instance.
8249
8254
Js::PropertyId propertyId = pnodeNameTarget->PropertyIdFromNameNode ();
8250
- EmitMethodFld (pnodeNameTarget, *callObjLocation, propertyId, byteCodeGenerator, funcInfo);
8255
+ EmitMethodFld (pnodeCall, pnodeNameTarget, *callObjLocation, propertyId, byteCodeGenerator, funcInfo);
8251
8256
break ;
8252
8257
}
8253
8258
}
@@ -8403,7 +8408,7 @@ void EmitCallInstrNoEvalComponents(
8403
8408
Assert (pnodeTarget->AsParseNodeBin ()->pnode2 ->nop == knopName);
8404
8409
Js::PropertyId propertyId = pnodeTarget->AsParseNodeBin ()->pnode2 ->AsParseNodeName ()->PropertyIdFromNameNode ();
8405
8410
8406
- EmitMethodFld (pnodeTarget, callObjLocation, propertyId, byteCodeGenerator, funcInfo);
8411
+ EmitMethodFld (pnodeCall, pnodeTarget, callObjLocation, propertyId, byteCodeGenerator, funcInfo);
8407
8412
EmitCallI (pnodeCall, /* fEvaluateComponents*/ FALSE , fIsEval , fHasNewTarget , actualArgCount, byteCodeGenerator, funcInfo, callSiteId, spreadIndices);
8408
8413
}
8409
8414
break ;
@@ -8427,7 +8432,7 @@ void EmitCallInstrNoEvalComponents(
8427
8432
funcInfo->ReleaseTmpRegister (callObjLocation);
8428
8433
8429
8434
Js::PropertyId propertyId = pnodeTarget->AsParseNodeName ()->PropertyIdFromNameNode ();
8430
- EmitMethodFld (pnodeTarget, callObjLocation, propertyId, byteCodeGenerator, funcInfo);
8435
+ EmitMethodFld (pnodeCall, pnodeTarget, callObjLocation, propertyId, byteCodeGenerator, funcInfo);
8431
8436
EmitCallI (pnodeCall, /* fEvaluateComponents*/ FALSE , fIsEval , fHasNewTarget , actualArgCount, byteCodeGenerator, funcInfo, callSiteId, spreadIndices);
8432
8437
break ;
8433
8438
}
@@ -8652,7 +8657,7 @@ void EmitCall(
8652
8657
}
8653
8658
else
8654
8659
{
8655
- EmitCallTarget (pnodeTarget, fSideEffectArgs , &thisLocation, &releaseThisLocation, &callObjLocation, byteCodeGenerator, funcInfo, &callApplyCallSiteId);
8660
+ EmitCallTarget (pnodeCall, pnodeTarget, fSideEffectArgs , &thisLocation, &releaseThisLocation, &callObjLocation, byteCodeGenerator, funcInfo, &callApplyCallSiteId);
8656
8661
}
8657
8662
}
8658
8663
@@ -8704,7 +8709,7 @@ void EmitInvoke(
8704
8709
ByteCodeGenerator* byteCodeGenerator,
8705
8710
FuncInfo* funcInfo)
8706
8711
{
8707
- EmitMethodFld (false , false , location, callObjLocation, propertyId, byteCodeGenerator, funcInfo);
8712
+ EmitMethodFld (false , false , false , location, callObjLocation, propertyId, byteCodeGenerator, funcInfo);
8708
8713
8709
8714
funcInfo->StartRecordingOutArgs (1 );
8710
8715
@@ -8724,7 +8729,7 @@ void EmitInvoke(
8724
8729
FuncInfo* funcInfo,
8725
8730
Js::RegSlot arg1Location)
8726
8731
{
8727
- EmitMethodFld (false , false , location, callObjLocation, propertyId, byteCodeGenerator, funcInfo);
8732
+ EmitMethodFld (false , false , false , location, callObjLocation, propertyId, byteCodeGenerator, funcInfo);
8728
8733
8729
8734
funcInfo->StartRecordingOutArgs (2 );
8730
8735
0 commit comments