@@ -22,22 +22,18 @@ void VisitClearTmpRegs(ParseNode * pnode, ByteCodeGenerator * byteCodeGenerator,
2222
2323/* *
2424 * This function generates the common code for null-propagation / optional-chaining.
25- * This works similar to how the c# compiler emits byte-code for optional-chaining.
2625 */
2726static void EmitNullPropagation (Js::RegSlot targetObjectSlot, ByteCodeGenerator *byteCodeGenerator, FuncInfo *funcInfo, bool isNullPropagating) {
2827 if (!isNullPropagating)
2928 return ;
3029
3130 Assert (funcInfo->currentOptionalChain != 0 );
3231
33- Js::ByteCodeLabel continueLabel = byteCodeGenerator->Writer ()->DefineLabel ();
34- byteCodeGenerator->Writer ()->BrReg2 (Js::OpCode::BrNeq_A, continueLabel, targetObjectSlot, funcInfo->nullConstantRegister );
35- // if (targetObject == null)
36- {
37- byteCodeGenerator->Writer ()->Reg1 (Js::OpCode::LdUndef, funcInfo->currentOptionalChain ->resultSlot ); // result = undefined
38- byteCodeGenerator->Writer ()->Br (funcInfo->currentOptionalChain ->skipLabel );
39- }
40- byteCodeGenerator->Writer ()->MarkLabel (continueLabel);
32+ // if (targetObject == null) goto chainEnd;
33+ byteCodeGenerator->Writer ()->BrReg2 (
34+ Js::OpCode::BrEq_A, funcInfo->currentOptionalChain ->skipLabel ,
35+ targetObjectSlot, funcInfo->nullConstantRegister
36+ );
4137}
4238
4339bool CallTargetIsArray (ParseNode *pnode)
@@ -11627,18 +11623,21 @@ void Emit(ParseNode* pnode, ByteCodeGenerator* byteCodeGenerator, FuncInfo* func
1162711623 }
1162811624
1162911625 case knopOptChain: {
11630- Js::ByteCodeLabel skipLabel = byteCodeGenerator->Writer ()->DefineLabel ();
11631- Js::RegSlot targetRegSlot = funcInfo->AcquireLoc (pnode);
11626+ FuncInfo::OptionalChainInfo *previousChain = funcInfo->currentOptionalChain ;
1163211627
11633- FuncInfo::OptionalChainInfo* previousChain = funcInfo-> currentOptionalChain ;
11634- FuncInfo::OptionalChainInfo currentOptionalChain = FuncInfo::OptionalChainInfo (skipLabel, targetRegSlot );
11628+ Js::ByteCodeLabel skipLabel = byteCodeGenerator-> Writer ()-> DefineLabel () ;
11629+ FuncInfo::OptionalChainInfo currentOptionalChain = FuncInfo::OptionalChainInfo (skipLabel);
1163511630 funcInfo->currentOptionalChain = ¤tOptionalChain;
1163611631
11632+ Js::RegSlot resultSlot = funcInfo->AcquireLoc (pnode);
11633+ byteCodeGenerator->Writer ()->Reg1 (Js::OpCode::LdUndef, resultSlot); // result = undefined
11634+
11635+ // emit chain
1163711636 ParseNodePtr innerNode = pnode->AsParseNodeUni ()->pnode1 ;
1163811637 Emit (innerNode, byteCodeGenerator, funcInfo, false );
1163911638
1164011639 // Copy result
11641- byteCodeGenerator->Writer ()->Reg2 (Js::OpCode::Ld_A, targetRegSlot , innerNode->location );
11640+ byteCodeGenerator->Writer ()->Reg2 (Js::OpCode::Ld_A, resultSlot , innerNode->location );
1164211641 funcInfo->ReleaseLoc (innerNode);
1164311642
1164411643 byteCodeGenerator->Writer ()->MarkLabel (skipLabel);
0 commit comments