@@ -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,38 @@ 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 ;
63
+ innerNode->location = funcInfo->AcquireLoc(pnodeOptChain) ;
69
64
70
65
// emit chain expression
71
66
// Every `?.` node will call `EmitNullPropagation`
72
67
// `EmitNullPropagation` short-circuits to `skipLabel` in case of a nullish value
73
68
emitChainContent(innerNode);
74
69
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
+
75
81
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
+ }
76
92
funcInfo->currentOptionalChainSkipLabel = previousSkipLabel;
77
93
}
78
94
0 commit comments