@@ -60,12 +60,13 @@ static void EmitOptionalChainWrapper(ParseNodeUni *pnodeOptChain, ByteCodeGenera
6060 // Copy values from wrapper to inner expression
6161 ParseNodePtr innerNode = pnodeOptChain->pnode1 ;
6262 innerNode->isUsed = pnodeOptChain->isUsed ;
63- innerNode->location = funcInfo-> AcquireLoc (pnodeOptChain) ;
63+ innerNode->location = pnodeOptChain-> location ;
6464
6565 // emit chain expression
6666 // Every `?.` node will call `EmitNullPropagation`
6767 // `EmitNullPropagation` short-circuits to `skipLabel` in case of a nullish value
6868 emitChainContent (innerNode);
69+ pnodeOptChain->location = innerNode->location ;
6970
7071 Js::ByteCodeLabel doneLabel = Js::Constants::NoRegister;
7172 if (pnodeOptChain->isUsed )
@@ -89,6 +90,7 @@ static void EmitOptionalChainWrapper(ParseNodeUni *pnodeOptChain, ByteCodeGenera
8990 byteCodeGenerator->Writer ()->Reg2 (Js::OpCode::Ld_A_ReuseLoc, pnodeOptChain->location , funcInfo->undefinedConstantRegister );
9091 byteCodeGenerator->Writer ()->MarkLabel (doneLabel);
9192 }
93+
9294 funcInfo->currentOptionalChainSkipLabel = previousSkipLabel;
9395}
9496
@@ -11209,6 +11211,81 @@ void TrackGlobalIntAssignments(ParseNodePtr pnode, ByteCodeGenerator * byteCodeG
1120911211 }
1121011212}
1121111213
11214+ static void EmitDelete (ParseNode *pnode, ParseNode *pexpr, ByteCodeGenerator *byteCodeGenerator, FuncInfo *funcInfo) {
11215+ switch (pexpr->nop )
11216+ {
11217+ case knopOptChain:
11218+ EmitOptionalChainWrapper (pexpr->AsParseNodeUni (), byteCodeGenerator, funcInfo, [&](ParseNode *innerNode) {
11219+ EmitDelete (innerNode, innerNode, byteCodeGenerator, funcInfo);
11220+ });
11221+ pnode->location = pexpr->location ;
11222+ break ;
11223+ case knopName:
11224+ {
11225+ ParseNodeName *pnodeName = pexpr->AsParseNodeName ();
11226+ if (pnodeName->IsSpecialName ())
11227+ {
11228+ funcInfo->AcquireLoc (pnode);
11229+ byteCodeGenerator->Writer ()->Reg1 (Js::OpCode::LdTrue, pnode->location );
11230+ }
11231+ else
11232+ {
11233+ funcInfo->AcquireLoc (pnode);
11234+ byteCodeGenerator->EmitPropDelete (pnode->location , pnodeName->sym , pnodeName->pid , funcInfo);
11235+ }
11236+ break ;
11237+ }
11238+ case knopDot:
11239+ {
11240+ ParseNodeBin *pnodeDot = pexpr->AsParseNodeBin ();
11241+ ParseNode *pnode1 = pnodeDot->pnode1 ;
11242+ ParseNode *pnode2 = pnodeDot->pnode2 ;
11243+
11244+ if (ByteCodeGenerator::IsSuper (pnode1))
11245+ {
11246+ byteCodeGenerator->Writer ()->W1 (Js::OpCode::RuntimeReferenceError, SCODE_CODE (JSERR_DeletePropertyWithSuper));
11247+
11248+ funcInfo->AcquireLoc (pnode);
11249+ byteCodeGenerator->Writer ()->Reg1 (Js::OpCode::LdUndef, pnode->location );
11250+ }
11251+ else
11252+ {
11253+ Emit (pnode1, byteCodeGenerator, funcInfo, false );
11254+ EmitNullPropagation (pnode1->location , byteCodeGenerator, funcInfo, pnodeDot->isNullPropagating );
11255+
11256+ funcInfo->ReleaseLoc (pnode1);
11257+ Js::PropertyId propertyId = pnode2->AsParseNodeName ()->PropertyIdFromNameNode ();
11258+ funcInfo->AcquireLoc (pnode);
11259+ byteCodeGenerator->Writer ()->Property (Js::OpCode::DeleteFld, pnode->location , pnode1->location ,
11260+ funcInfo->FindOrAddReferencedPropertyId (propertyId), byteCodeGenerator->forceStrictModeForClassComputedPropertyName );
11261+ }
11262+
11263+ break ;
11264+ }
11265+ case knopIndex:
11266+ {
11267+ ParseNodeBin *pnodeIndex = pexpr->AsParseNodeBin ();
11268+ ParseNode *pnode1 = pnodeIndex->pnode1 ;
11269+ ParseNode *pnode2 = pnodeIndex->pnode2 ;
11270+
11271+ EmitBinaryOpnds (pnode1, pnode2, byteCodeGenerator, funcInfo, Js::Constants::NoRegister, pnodeIndex->isNullPropagating );
11272+ funcInfo->ReleaseLoc (pnode2);
11273+ funcInfo->ReleaseLoc (pnode1);
11274+ funcInfo->AcquireLoc (pnode);
11275+ byteCodeGenerator->Writer ()->Element (Js::OpCode::DeleteElemI_A, pnode->location , pnode1->location , pnode2->location );
11276+ break ;
11277+ }
11278+ default :
11279+ {
11280+ Emit (pexpr, byteCodeGenerator, funcInfo, false );
11281+ funcInfo->ReleaseLoc (pexpr);
11282+ byteCodeGenerator->Writer ()->Reg2 (
11283+ Js::OpCode::Delete_A, funcInfo->AcquireLoc (pnode), pexpr->location );
11284+ break ;
11285+ }
11286+ }
11287+ }
11288+
1121211289void Emit (ParseNode* pnode, ByteCodeGenerator* byteCodeGenerator, FuncInfo* funcInfo, BOOL fReturnValue , bool isConstructorCall, bool isTopLevel)
1121311290{
1121411291 if (pnode == nullptr )
@@ -11570,63 +11647,7 @@ void Emit(ParseNode* pnode, ByteCodeGenerator* byteCodeGenerator, FuncInfo* func
1157011647 {
1157111648 ParseNode *pexpr = pnode->AsParseNodeUni ()->pnode1 ;
1157211649 byteCodeGenerator->StartStatement (pnode);
11573- switch (pexpr->nop )
11574- {
11575- case knopName:
11576- {
11577- ParseNodeName * pnodeName = pexpr->AsParseNodeName ();
11578- if (pnodeName->IsSpecialName ())
11579- {
11580- funcInfo->AcquireLoc (pnode);
11581- byteCodeGenerator->Writer ()->Reg1 (Js::OpCode::LdTrue, pnode->location );
11582- }
11583- else
11584- {
11585- funcInfo->AcquireLoc (pnode);
11586- byteCodeGenerator->EmitPropDelete (pnode->location , pnodeName->sym , pnodeName->pid , funcInfo);
11587- }
11588- break ;
11589- }
11590- case knopDot:
11591- {
11592- if (ByteCodeGenerator::IsSuper (pexpr->AsParseNodeBin ()->pnode1 ))
11593- {
11594- byteCodeGenerator->Writer ()->W1 (Js::OpCode::RuntimeReferenceError, SCODE_CODE (JSERR_DeletePropertyWithSuper));
11595-
11596- funcInfo->AcquireLoc (pnode);
11597- byteCodeGenerator->Writer ()->Reg1 (Js::OpCode::LdUndef, pnode->location );
11598- }
11599- else
11600- {
11601- Emit (pexpr->AsParseNodeBin ()->pnode1 , byteCodeGenerator, funcInfo, false );
11602-
11603- funcInfo->ReleaseLoc (pexpr->AsParseNodeBin ()->pnode1 );
11604- Js::PropertyId propertyId = pexpr->AsParseNodeBin ()->pnode2 ->AsParseNodeName ()->PropertyIdFromNameNode ();
11605- funcInfo->AcquireLoc (pnode);
11606- byteCodeGenerator->Writer ()->Property (Js::OpCode::DeleteFld, pnode->location , pexpr->AsParseNodeBin ()->pnode1 ->location ,
11607- funcInfo->FindOrAddReferencedPropertyId (propertyId), byteCodeGenerator->forceStrictModeForClassComputedPropertyName );
11608- }
11609-
11610- break ;
11611- }
11612- case knopIndex:
11613- {
11614- EmitBinaryOpnds (pexpr->AsParseNodeBin ()->pnode1 , pexpr->AsParseNodeBin ()->pnode2 , byteCodeGenerator, funcInfo);
11615- funcInfo->ReleaseLoc (pexpr->AsParseNodeBin ()->pnode2 );
11616- funcInfo->ReleaseLoc (pexpr->AsParseNodeBin ()->pnode1 );
11617- funcInfo->AcquireLoc (pnode);
11618- byteCodeGenerator->Writer ()->Element (Js::OpCode::DeleteElemI_A, pnode->location , pexpr->AsParseNodeBin ()->pnode1 ->location , pexpr->AsParseNodeBin ()->pnode2 ->location );
11619- break ;
11620- }
11621- default :
11622- {
11623- Emit (pexpr, byteCodeGenerator, funcInfo, false );
11624- funcInfo->ReleaseLoc (pexpr);
11625- byteCodeGenerator->Writer ()->Reg2 (
11626- Js::OpCode::Delete_A, funcInfo->AcquireLoc (pnode), pexpr->location );
11627- break ;
11628- }
11629- }
11650+ EmitDelete (pnode, pexpr, byteCodeGenerator, funcInfo);
1163011651 byteCodeGenerator->EndStatement (pnode);
1163111652 break ;
1163211653 }
0 commit comments