@@ -57,38 +57,40 @@ static void EmitOptionalChainWrapper(ParseNodeUni *pnodeOptChain, ByteCodeGenera
5757 Js::ByteCodeLabel skipLabel = byteCodeGenerator->Writer ()->DefineLabel ();
5858 funcInfo->currentOptionalChainSkipLabel = skipLabel;
5959
60+ // Acquire slot for the result value
61+ Js::RegSlot resultSlot = funcInfo->AcquireLoc (pnodeOptChain);
62+
6063 // Copy values from wrapper to inner expression
6164 ParseNodePtr innerNode = pnodeOptChain->pnode1 ;
6265 innerNode->isUsed = pnodeOptChain->isUsed ;
66+ innerNode->location = resultSlot;
6367
6468 // emit chain expression
6569 // Every `?.` node will call `EmitNullPropagation`
6670 // `EmitNullPropagation` short-circuits to `skipLabel` in case of a nullish value
6771 emitChainContent (innerNode);
68- funcInfo->ReleaseLoc (innerNode);
6972
70- if (innerNode->isUsed )
73+ Js::ByteCodeLabel doneLabel = Js::Constants::NoRegister;
74+ if (pnodeOptChain->isUsed )
7175 {
72- Assert (Js::Constants::NoRegister != innerNode->location );
73-
74- // Acquire slot for the result value
75- Js::RegSlot resultSlot = funcInfo->AcquireLoc (pnodeOptChain);
76- // Copy chain result
77- byteCodeGenerator->Writer ()->Reg2 (Js::OpCode::Ld_A, resultSlot, innerNode->location );
76+ Assert (innerNode->isUsed );
77+ Assert (resultSlot == innerNode->location );
7878
7979 // Skip short-circuiting logic
80- Js::ByteCodeLabel doneLabel = byteCodeGenerator->Writer ()->DefineLabel ();
80+ doneLabel = byteCodeGenerator->Writer ()->DefineLabel ();
8181 byteCodeGenerator->Writer ()->Br (doneLabel);
82+ }
8283
83- // Set `undefined` on short-circuiting
8484 byteCodeGenerator->Writer ()->MarkLabel (skipLabel);
85- byteCodeGenerator->Writer ()->Reg2 (Js::OpCode::Ld_A_ReuseLoc, resultSlot, funcInfo->undefinedConstantRegister );
8685
87- byteCodeGenerator->Writer ()->MarkLabel (doneLabel);
88- }
89- else
86+ if (pnodeOptChain->isUsed )
9087 {
91- byteCodeGenerator->Writer ()->MarkLabel (skipLabel);
88+ Assert (innerNode->isUsed );
89+ Assert (Js::Constants::NoRegister != resultSlot);
90+
91+ // Set `undefined` on short-circuiting
92+ byteCodeGenerator->Writer ()->Reg2 (Js::OpCode::Ld_A_ReuseLoc, resultSlot, funcInfo->undefinedConstantRegister );
93+ byteCodeGenerator->Writer ()->MarkLabel (doneLabel);
9294 }
9395 funcInfo->currentOptionalChainSkipLabel = previousSkipLabel;
9496}
0 commit comments