@@ -39,7 +39,7 @@ static void EmitNullPropagation(Js::RegSlot targetObjectSlot, ByteCodeGenerator
3939 // if (targetObject == null) goto skipLabel;
4040 byteCodeGenerator->Writer ()->BrReg2 (
4141 Js::OpCode::BrEq_A, funcInfo->currentOptionalChainSkipLabel ,
42- targetObjectSlot, funcInfo->nullConstantRegister
42+ targetObjectSlot, funcInfo->undefinedConstantRegister
4343 );
4444}
4545
@@ -57,22 +57,38 @@ 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- // Prefill it with `undefined` (Fallback for short-circuiting)
62- Js::RegSlot resultSlot = funcInfo->AcquireLoc (pnodeOptChain);
63- byteCodeGenerator->Writer ()->Reg1 (Js::OpCode::LdUndef, resultSlot);
64-
6560 // Copy values from wrapper to inner expression
6661 ParseNodePtr innerNode = pnodeOptChain->pnode1 ;
6762 innerNode->isUsed = pnodeOptChain->isUsed ;
68- innerNode->location = pnodeOptChain-> location ;
63+ innerNode->location = funcInfo-> AcquireLoc (pnodeOptChain) ;
6964
7065 // emit chain expression
7166 // Every `?.` node will call `EmitNullPropagation`
7267 // `EmitNullPropagation` short-circuits to `skipLabel` in case of a nullish value
7368 emitChainContent (innerNode);
7469
70+ Js::ByteCodeLabel doneLabel = Js::Constants::NoRegister;
71+ if (pnodeOptChain->isUsed )
72+ {
73+ Assert (innerNode->isUsed );
74+ Assert (Js::Constants::NoRegister != innerNode->location );
75+
76+ // Skip short-circuiting logic
77+ doneLabel = byteCodeGenerator->Writer ()->DefineLabel ();
78+ byteCodeGenerator->Writer ()->Br (doneLabel);
79+ }
80+
7581 byteCodeGenerator->Writer ()->MarkLabel (skipLabel);
82+
83+ if (pnodeOptChain->isUsed )
84+ {
85+ Assert (innerNode->isUsed );
86+ Assert (Js::Constants::NoRegister != pnodeOptChain->location );
87+
88+ // Set `undefined` on short-circuiting
89+ byteCodeGenerator->Writer ()->Reg2 (Js::OpCode::Ld_A_ReuseLoc, pnodeOptChain->location , funcInfo->undefinedConstantRegister );
90+ byteCodeGenerator->Writer ()->MarkLabel (doneLabel);
91+ }
7692 funcInfo->currentOptionalChainSkipLabel = previousSkipLabel;
7793}
7894
0 commit comments