Skip to content

Commit c8297ec

Browse files
Fix jit _ReuseLoc
1 parent ba32362 commit c8297ec

File tree

2 files changed

+26
-8
lines changed

2 files changed

+26
-8
lines changed

lib/Runtime/ByteCode/ByteCodeEmitter.cpp

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -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

lib/Runtime/ByteCode/ByteCodeGenerator.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4962,10 +4962,12 @@ void AssignRegisters(ParseNode *pnode, ByteCodeGenerator *byteCodeGenerator)
49624962
CheckMaybeEscapedUse(pnode->AsParseNodeUni()->pnode1, byteCodeGenerator);
49634963
break;
49644964
case knopCoalesce:
4965-
case knopOptChain:
49664965
case knopObject:
49674966
byteCodeGenerator->AssignNullConstRegister();
49684967
break;
4968+
case knopOptChain:
4969+
byteCodeGenerator->AssignUndefinedConstRegister();
4970+
break;
49694971
case knopClassDecl:
49704972
{
49714973
FuncInfo * topFunc = byteCodeGenerator->TopFuncInfo();

0 commit comments

Comments
 (0)