@@ -57,38 +57,40 @@ 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
+ Js::RegSlot resultSlot = funcInfo->AcquireLoc (pnodeOptChain);
62
+
60
63
// Copy values from wrapper to inner expression
61
64
ParseNodePtr innerNode = pnodeOptChain->pnode1 ;
62
65
innerNode->isUsed = pnodeOptChain->isUsed ;
66
+ innerNode->location = resultSlot;
63
67
64
68
// emit chain expression
65
69
// Every `?.` node will call `EmitNullPropagation`
66
70
// `EmitNullPropagation` short-circuits to `skipLabel` in case of a nullish value
67
71
emitChainContent (innerNode);
68
- funcInfo->ReleaseLoc (innerNode);
69
72
70
- if (innerNode->isUsed )
73
+ Js::ByteCodeLabel doneLabel = Js::Constants::NoRegister;
74
+ if (pnodeOptChain->isUsed )
71
75
{
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 );
78
78
79
79
// Skip short-circuiting logic
80
- Js::ByteCodeLabel doneLabel = byteCodeGenerator->Writer ()->DefineLabel ();
80
+ doneLabel = byteCodeGenerator->Writer ()->DefineLabel ();
81
81
byteCodeGenerator->Writer ()->Br (doneLabel);
82
+ }
82
83
83
- // Set `undefined` on short-circuiting
84
84
byteCodeGenerator->Writer ()->MarkLabel (skipLabel);
85
- byteCodeGenerator->Writer ()->Reg2 (Js::OpCode::Ld_A_ReuseLoc, resultSlot, funcInfo->undefinedConstantRegister );
86
85
87
- byteCodeGenerator->Writer ()->MarkLabel (doneLabel);
88
- }
89
- else
86
+ if (pnodeOptChain->isUsed )
90
87
{
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);
92
94
}
93
95
funcInfo->currentOptionalChainSkipLabel = previousSkipLabel;
94
96
}
0 commit comments