@@ -57,22 +57,28 @@ 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
+ Js::ByteCodeLabel doneLabel = byteCodeGenerator->Writer()->DefineLabel();
71
+
72
+ // Acquire slot for the result value
73
+ Js::RegSlot resultSlot = funcInfo->AcquireLoc(pnodeOptChain);
74
+ byteCodeGenerator->Writer()->Reg2(Js::OpCode::Ld_A_ReuseLoc, resultSlot, innerNode->location);
75
+ byteCodeGenerator->Writer()->Br(Js::OpCode::Br, doneLabel);
74
76
75
77
byteCodeGenerator->Writer()->MarkLabel(skipLabel);
78
+ // Fill with `undefined` (short-circuiting)
79
+ byteCodeGenerator->Writer()->Reg1(Js::OpCode::LdUndef, resultSlot);
80
+
81
+ byteCodeGenerator->Writer()->MarkLabel(doneLabel);
76
82
funcInfo->currentOptionalChainSkipLabel = previousSkipLabel;
77
83
}
78
84
0 commit comments