mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-09 03:52:19 +02:00
Made null coalescing short-circuit
This commit is contained in:
parent
4c40028b33
commit
9a854a0237
1 changed files with 60 additions and 58 deletions
|
@ -20440,11 +20440,70 @@ void BfExprEvaluator::PerformBinaryOperation(BfExpression* leftExpression, BfExp
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
BfType* wantType = leftValue.mType;
|
BfType* wantType = leftValue.mType;
|
||||||
if ((binaryOp == BfBinaryOp_LeftShift) || (binaryOp == BfBinaryOp_RightShift))
|
if ((binaryOp == BfBinaryOp_LeftShift) || (binaryOp == BfBinaryOp_RightShift))
|
||||||
wantType = NULL; // Don't presume
|
wantType = NULL; // Don't presume
|
||||||
wantType = mModule->FixIntUnknown(wantType);
|
wantType = mModule->FixIntUnknown(wantType);
|
||||||
|
|
||||||
|
if ((binaryOp == BfBinaryOp_NullCoalesce) && (leftValue) && ((leftValue.mType->IsPointer()) || (leftValue.mType->IsFunction()) || (leftValue.mType->IsObject())))
|
||||||
|
{
|
||||||
|
auto prevBB = mModule->mBfIRBuilder->GetInsertBlock();
|
||||||
|
|
||||||
|
auto rhsBB = mModule->mBfIRBuilder->CreateBlock("nullc.rhs");
|
||||||
|
auto endBB = mModule->mBfIRBuilder->CreateBlock("nullc.end");
|
||||||
|
|
||||||
|
BfIRValue isNull;
|
||||||
|
if (leftValue.mType->IsFunction())
|
||||||
|
isNull = mModule->mBfIRBuilder->CreateIsNull(
|
||||||
|
mModule->mBfIRBuilder->CreateIntToPtr(leftValue.mValue, mModule->mBfIRBuilder->MapType(mModule->GetPrimitiveType(BfTypeCode_NullPtr))));
|
||||||
|
else
|
||||||
|
isNull = mModule->mBfIRBuilder->CreateIsNull(leftValue.mValue);
|
||||||
|
mModule->mBfIRBuilder->CreateCondBr(isNull, rhsBB, endBB);
|
||||||
|
|
||||||
|
mModule->AddBasicBlock(rhsBB);
|
||||||
|
rightValue = mModule->CreateValueFromExpression(rightExpression, wantType, (BfEvalExprFlags)((mBfEvalExprFlags & BfEvalExprFlags_InheritFlags) | BfEvalExprFlags_NoCast));
|
||||||
|
if (!rightValue)
|
||||||
|
{
|
||||||
|
mModule->AssertErrorState();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto rightToLeftValue = mModule->CastToValue(rightExpression, rightValue, leftValue.mType, BfCastFlags_SilentFail);
|
||||||
|
if (rightToLeftValue)
|
||||||
|
{
|
||||||
|
rightValue = BfTypedValue(rightToLeftValue, leftValue.mType);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto leftToRightValue = mModule->CastToValue(leftExpression, leftValue, rightValue.mType, BfCastFlags_SilentFail);
|
||||||
|
if (leftToRightValue)
|
||||||
|
{
|
||||||
|
leftValue = BfTypedValue(leftToRightValue, rightValue.mType);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Note: Annoying trigraph split for '??'
|
||||||
|
mModule->Fail(StrFormat("Operator '?" "?' cannot be applied to operands of type '%s' and '%s'",
|
||||||
|
mModule->TypeToString(leftValue.mType).c_str(), mModule->TypeToString(rightValue.mType).c_str()), opToken);
|
||||||
|
leftValue = mModule->GetDefaultTypedValue(rightValue.mType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mModule->mBfIRBuilder->CreateBr(endBB);
|
||||||
|
|
||||||
|
auto endRhsBB = mModule->mBfIRBuilder->GetInsertBlock();
|
||||||
|
mModule->AddBasicBlock(endBB);
|
||||||
|
auto phi = mModule->mBfIRBuilder->CreatePhi(mModule->mBfIRBuilder->MapType(leftValue.mType), 2);
|
||||||
|
mModule->mBfIRBuilder->AddPhiIncoming(phi, leftValue.mValue, prevBB);
|
||||||
|
mModule->mBfIRBuilder->AddPhiIncoming(phi, rightValue.mValue, endRhsBB);
|
||||||
|
mResult = BfTypedValue(phi, leftValue.mType);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
rightValue = mModule->CreateValueFromExpression(rightExpression, wantType, (BfEvalExprFlags)((mBfEvalExprFlags & BfEvalExprFlags_InheritFlags) | BfEvalExprFlags_NoCast));
|
rightValue = mModule->CreateValueFromExpression(rightExpression, wantType, (BfEvalExprFlags)((mBfEvalExprFlags & BfEvalExprFlags_InheritFlags) | BfEvalExprFlags_NoCast));
|
||||||
if ((!leftValue) || (!rightValue))
|
if ((!leftValue) || (!rightValue))
|
||||||
return;
|
return;
|
||||||
|
@ -20652,63 +20711,6 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((binaryOp == BfBinaryOp_NullCoalesce) && ((leftValue.mType->IsPointer()) || (leftValue.mType->IsFunction()) || (leftValue.mType->IsObject())))
|
|
||||||
{
|
|
||||||
auto prevBB = mModule->mBfIRBuilder->GetInsertBlock();
|
|
||||||
|
|
||||||
auto rhsBB = mModule->mBfIRBuilder->CreateBlock("nullc.rhs");
|
|
||||||
auto endBB = mModule->mBfIRBuilder->CreateBlock("nullc.end");
|
|
||||||
|
|
||||||
BfIRValue isNull;
|
|
||||||
if (leftValue.mType->IsFunction())
|
|
||||||
isNull = mModule->mBfIRBuilder->CreateIsNull(
|
|
||||||
mModule->mBfIRBuilder->CreateIntToPtr(leftValue.mValue, mModule->mBfIRBuilder->MapType(mModule->GetPrimitiveType(BfTypeCode_NullPtr))));
|
|
||||||
else
|
|
||||||
isNull = mModule->mBfIRBuilder->CreateIsNull(leftValue.mValue);
|
|
||||||
mModule->mBfIRBuilder->CreateCondBr(isNull, rhsBB, endBB);
|
|
||||||
|
|
||||||
mModule->AddBasicBlock(rhsBB);
|
|
||||||
if (!rightValue)
|
|
||||||
{
|
|
||||||
mModule->AssertErrorState();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
auto rightToLeftValue = mModule->CastToValue(rightExpression, rightValue, leftValue.mType, BfCastFlags_SilentFail);
|
|
||||||
if (rightToLeftValue)
|
|
||||||
{
|
|
||||||
rightValue = BfTypedValue(rightToLeftValue, leftValue.mType);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
auto leftToRightValue = mModule->CastToValue(leftExpression, leftValue, rightValue.mType, BfCastFlags_SilentFail);
|
|
||||||
if (leftToRightValue)
|
|
||||||
{
|
|
||||||
leftValue = BfTypedValue(leftToRightValue, rightValue.mType);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Note: Annoying trigraph split for '??'
|
|
||||||
mModule->Fail(StrFormat("Operator '?" "?' cannot be applied to operands of type '%s' and '%s'",
|
|
||||||
mModule->TypeToString(leftValue.mType).c_str(), mModule->TypeToString(rightValue.mType).c_str()), opToken);
|
|
||||||
leftValue = mModule->GetDefaultTypedValue(rightValue.mType);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mModule->mBfIRBuilder->CreateBr(endBB);
|
|
||||||
|
|
||||||
auto endRhsBB = mModule->mBfIRBuilder->GetInsertBlock();
|
|
||||||
mModule->AddBasicBlock(endBB);
|
|
||||||
auto phi = mModule->mBfIRBuilder->CreatePhi(mModule->mBfIRBuilder->MapType(leftValue.mType), 2);
|
|
||||||
mModule->mBfIRBuilder->AddPhiIncoming(phi, leftValue.mValue, prevBB);
|
|
||||||
mModule->mBfIRBuilder->AddPhiIncoming(phi, rightValue.mValue, endRhsBB);
|
|
||||||
mResult = BfTypedValue(phi, leftValue.mType);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((binaryOp == BfBinaryOp_LeftShift) || (binaryOp == BfBinaryOp_RightShift))
|
if ((binaryOp == BfBinaryOp_LeftShift) || (binaryOp == BfBinaryOp_RightShift))
|
||||||
{
|
{
|
||||||
forceLeftType = true;
|
forceLeftType = true;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue