@@ -22,22 +22,18 @@ void VisitClearTmpRegs(ParseNode * pnode, ByteCodeGenerator * byteCodeGenerator,
22
22
23
23
/* *
24
24
* 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.
26
25
*/
27
26
static void EmitNullPropagation (Js::RegSlot targetObjectSlot, ByteCodeGenerator *byteCodeGenerator, FuncInfo *funcInfo, bool isNullPropagating) {
28
27
if (!isNullPropagating)
29
28
return ;
30
29
31
30
Assert (funcInfo->currentOptionalChain != 0 );
32
31
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
+ );
41
37
}
42
38
43
39
bool CallTargetIsArray (ParseNode *pnode)
@@ -11627,18 +11623,21 @@ void Emit(ParseNode* pnode, ByteCodeGenerator* byteCodeGenerator, FuncInfo* func
11627
11623
}
11628
11624
11629
11625
case knopOptChain: {
11630
- Js::ByteCodeLabel skipLabel = byteCodeGenerator->Writer ()->DefineLabel ();
11631
- Js::RegSlot targetRegSlot = funcInfo->AcquireLoc (pnode);
11626
+ FuncInfo::OptionalChainInfo *previousChain = funcInfo->currentOptionalChain ;
11632
11627
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);
11635
11630
funcInfo->currentOptionalChain = ¤tOptionalChain;
11636
11631
11632
+ Js::RegSlot resultSlot = funcInfo->AcquireLoc (pnode);
11633
+ byteCodeGenerator->Writer ()->Reg1 (Js::OpCode::LdUndef, resultSlot); // result = undefined
11634
+
11635
+ // emit chain
11637
11636
ParseNodePtr innerNode = pnode->AsParseNodeUni ()->pnode1 ;
11638
11637
Emit (innerNode, byteCodeGenerator, funcInfo, false );
11639
11638
11640
11639
// Copy result
11641
- byteCodeGenerator->Writer ()->Reg2 (Js::OpCode::Ld_A, targetRegSlot , innerNode->location );
11640
+ byteCodeGenerator->Writer ()->Reg2 (Js::OpCode::Ld_A, resultSlot , innerNode->location );
11642
11641
funcInfo->ReleaseLoc (innerNode);
11643
11642
11644
11643
byteCodeGenerator->Writer ()->MarkLabel (skipLabel);
0 commit comments