@@ -39,7 +39,7 @@ static void EmitNullPropagation(Js::RegSlot targetObjectSlot, ByteCodeGenerator
39
39
// if (targetObject == null) goto skipLabel;
40
40
byteCodeGenerator->Writer ()->BrReg2 (
41
41
Js::OpCode::BrEq_A, funcInfo->currentOptionalChainSkipLabel ,
42
- targetObjectSlot, funcInfo->nullConstantRegister
42
+ targetObjectSlot, funcInfo->undefinedConstantRegister
43
43
);
44
44
}
45
45
@@ -57,22 +57,30 @@ static void EmitOptionalChainWrapper(ParseNodeUni *pnodeOptChain, ByteCodeGenera
57
57
Js::ByteCodeLabel skipLabel = byteCodeGenerator->Writer ()->DefineLabel ();
58
58
funcInfo->currentOptionalChainSkipLabel = skipLabel;
59
59
60
- // Acquire slot for the result value
61
- // Prefill it with `undefined` (Fallback for short-circuiting)
62
- Js::RegSlot resultSlot = funcInfo->AcquireLoc (pnodeOptChain);
63
- byteCodeGenerator->Writer ()->Reg1 (Js::OpCode::LdUndef, resultSlot);
64
-
65
60
// Copy values from wrapper to inner expression
66
61
ParseNodePtr innerNode = pnodeOptChain->pnode1 ;
67
62
innerNode->isUsed = pnodeOptChain->isUsed ;
68
- innerNode->location = pnodeOptChain->location ;
69
63
70
64
// emit chain expression
71
65
// Every `?.` node will call `EmitNullPropagation`
72
66
// `EmitNullPropagation` short-circuits to `skipLabel` in case of a nullish value
73
67
emitChainContent (innerNode);
68
+ funcInfo->ReleaseLoc (innerNode);
69
+
70
+ // Acquire slot for the result value
71
+ Js::RegSlot resultSlot = funcInfo->AcquireLoc (pnodeOptChain);
72
+ // Copy chain result
73
+ byteCodeGenerator->Writer ()->Reg2 (Js::OpCode::Ld_A_ReuseLoc, resultSlot, innerNode->location );
74
+
75
+ // Skip short-circuiting logic
76
+ Js::ByteCodeLabel doneLabel = byteCodeGenerator->Writer ()->DefineLabel ();
77
+ byteCodeGenerator->Writer ()->Br (doneLabel);
74
78
79
+ // Set `undefined` on short-circuiting
75
80
byteCodeGenerator->Writer ()->MarkLabel (skipLabel);
81
+ byteCodeGenerator->Writer ()->Reg2 (Js::OpCode::Ld_A_ReuseLoc, resultSlot, funcInfo->undefinedConstantRegister );
82
+
83
+ byteCodeGenerator->Writer ()->MarkLabel (doneLabel);
76
84
funcInfo->currentOptionalChainSkipLabel = previousSkipLabel;
77
85
}
78
86
0 commit comments