Skip to content

Commit

Permalink
Use less branches
Browse files Browse the repository at this point in the history
  • Loading branch information
ShortDevelopment committed Apr 15, 2024
1 parent 2e96c32 commit 62873f5
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 17 deletions.
27 changes: 13 additions & 14 deletions lib/Runtime/ByteCode/ByteCodeEmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,22 +22,18 @@ void VisitClearTmpRegs(ParseNode * pnode, ByteCodeGenerator * byteCodeGenerator,

/**
* This function generates the common code for null-propagation / optional-chaining.
* This works similar to how the c# compiler emits byte-code for optional-chaining.
*/
static void EmitNullPropagation(Js::RegSlot targetObjectSlot, ByteCodeGenerator *byteCodeGenerator, FuncInfo *funcInfo, bool isNullPropagating) {
if (!isNullPropagating)
return;

Assert(funcInfo->currentOptionalChain != 0);

Js::ByteCodeLabel continueLabel = byteCodeGenerator->Writer()->DefineLabel();
byteCodeGenerator->Writer()->BrReg2(Js::OpCode::BrNeq_A, continueLabel, targetObjectSlot, funcInfo->nullConstantRegister);
// if (targetObject == null)
{
byteCodeGenerator->Writer()->Reg1(Js::OpCode::LdUndef, funcInfo->currentOptionalChain->resultSlot); // result = undefined
byteCodeGenerator->Writer()->Br(funcInfo->currentOptionalChain->skipLabel);
}
byteCodeGenerator->Writer()->MarkLabel(continueLabel);
// if (targetObject == null) goto chainEnd;
byteCodeGenerator->Writer()->BrReg2(
Js::OpCode::BrEq_A, funcInfo->currentOptionalChain->skipLabel,
targetObjectSlot, funcInfo->nullConstantRegister
);
}

bool CallTargetIsArray(ParseNode *pnode)
Expand Down Expand Up @@ -11627,18 +11623,21 @@ void Emit(ParseNode* pnode, ByteCodeGenerator* byteCodeGenerator, FuncInfo* func
}

case knopOptChain: {
Js::ByteCodeLabel skipLabel = byteCodeGenerator->Writer()->DefineLabel();
Js::RegSlot targetRegSlot = funcInfo->AcquireLoc(pnode);
FuncInfo::OptionalChainInfo *previousChain = funcInfo->currentOptionalChain;

FuncInfo::OptionalChainInfo* previousChain = funcInfo->currentOptionalChain;
FuncInfo::OptionalChainInfo currentOptionalChain = FuncInfo::OptionalChainInfo(skipLabel, targetRegSlot);
Js::ByteCodeLabel skipLabel = byteCodeGenerator->Writer()->DefineLabel();
FuncInfo::OptionalChainInfo currentOptionalChain = FuncInfo::OptionalChainInfo(skipLabel);
funcInfo->currentOptionalChain = &currentOptionalChain;

Js::RegSlot resultSlot = funcInfo->AcquireLoc(pnode);
byteCodeGenerator->Writer()->Reg1(Js::OpCode::LdUndef, resultSlot); // result = undefined

// emit chain
ParseNodePtr innerNode = pnode->AsParseNodeUni()->pnode1;
Emit(innerNode, byteCodeGenerator, funcInfo, false);

// Copy result
byteCodeGenerator->Writer()->Reg2(Js::OpCode::Ld_A, targetRegSlot, innerNode->location);
byteCodeGenerator->Writer()->Reg2(Js::OpCode::Ld_A, resultSlot, innerNode->location);
funcInfo->ReleaseLoc(innerNode);

byteCodeGenerator->Writer()->MarkLabel(skipLabel);
Expand Down
4 changes: 1 addition & 3 deletions lib/Runtime/ByteCode/FuncInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,11 +98,9 @@ class FuncInfo
uint currentInnerScopeIndex;
struct OptionalChainInfo {
Js::ByteCodeLabel skipLabel;
Js::RegSlot resultSlot;

OptionalChainInfo(Js::ByteCodeLabel skipLabel, Js::RegSlot resultSlot) {
OptionalChainInfo(Js::ByteCodeLabel skipLabel) {
this->skipLabel = skipLabel;
this->resultSlot = resultSlot;
}
} *currentOptionalChain;
#if DBG
Expand Down

0 comments on commit 62873f5

Please sign in to comment.