mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-10 04:22:20 +02:00
Allow comptime attempts on generic interface dispatches
This commit is contained in:
parent
4b8983a013
commit
f1d9964ba1
3 changed files with 45 additions and 25 deletions
|
@ -5214,7 +5214,7 @@ void BfExprEvaluator::PerformCallChecks(BfMethodInstance* methodInstance, BfAstN
|
|||
mModule->CheckErrorAttributes(methodInstance->GetOwner(), methodInstance, customAttributes, targetSrc);
|
||||
}
|
||||
|
||||
BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance* methodInstance, BfIRValue func, bool bypassVirtual, SizedArrayImpl<BfIRValue>& irArgs, BfTypedValue* sret, bool isTailCall)
|
||||
BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance* methodInstance, BfIRValue func, bool bypassVirtual, SizedArrayImpl<BfIRValue>& irArgs, BfTypedValue* sret, BfCreateCallFlags callFlags)
|
||||
{
|
||||
// static int sCallIdx = 0;
|
||||
// if (!mModule->mCompiler->mIsResolveOnly)
|
||||
|
@ -5457,6 +5457,11 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance*
|
|||
{
|
||||
doConstReturn = true;
|
||||
}
|
||||
else if (((callFlags & BfCreateCallFlags_GenericParamThis) != 0) && (methodInstance->GetOwner()->IsInterface()))
|
||||
{
|
||||
mModule->Warn(0, "Concrete method may fail to comptime during specialization", targetSrc);
|
||||
doConstReturn = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
CeEvalFlags evalFlags = CeEvalFlags_None;
|
||||
|
@ -5502,7 +5507,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance*
|
|||
{
|
||||
if (returnType->IsInstanceOf(mModule->mCompiler->mSpanTypeDef))
|
||||
{
|
||||
if (mExpectingType->IsUndefSizedArray())
|
||||
if ((mExpectingType != NULL) && (mExpectingType->IsUndefSizedArray()))
|
||||
{
|
||||
if (returnType->GetUnderlyingType() == mExpectingType->GetUnderlyingType())
|
||||
return mModule->GetDefaultTypedValue(mExpectingType, true, BfDefaultValueKind_Undef);
|
||||
|
@ -5922,7 +5927,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance*
|
|||
//argIdx++;
|
||||
}
|
||||
|
||||
if (isTailCall)
|
||||
if ((callFlags & BfCreateCallFlags_TailCall) != 0)
|
||||
mModule->mBfIRBuilder->SetTailCall(callInst);
|
||||
|
||||
if (methodDef->mIsNoReturn)
|
||||
|
@ -6001,9 +6006,9 @@ BfTypedValue BfExprEvaluator::CreateCall(BfMethodMatcher* methodMatcher, BfTyped
|
|||
|
||||
PerformCallChecks(moduleMethodInstance.mMethodInstance, methodMatcher->mTargetSrc);
|
||||
|
||||
BfCreateFallFlags callFlags = BfCreateFallFlags_None;
|
||||
BfCreateCallFlags callFlags = BfCreateCallFlags_None;
|
||||
if (methodMatcher->mAllowImplicitRef)
|
||||
callFlags = (BfCreateFallFlags)(callFlags | BfCreateFallFlags_AllowImplicitRef);
|
||||
callFlags = (BfCreateCallFlags)(callFlags | BfCreateCallFlags_AllowImplicitRef);
|
||||
return CreateCall(methodMatcher->mTargetSrc, target, BfTypedValue(), methodMatcher->mBestMethodDef, moduleMethodInstance, callFlags, methodMatcher->mArguments);
|
||||
}
|
||||
|
||||
|
@ -6335,10 +6340,10 @@ void BfExprEvaluator::AddCallDependencies(BfMethodInstance* methodInstance)
|
|||
}
|
||||
|
||||
//TODO: delete argumentsZ
|
||||
BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValue& inTarget, const BfTypedValue& origTarget, BfMethodDef* methodDef, BfModuleMethodInstance moduleMethodInstance, BfCreateFallFlags callFlags, SizedArrayImpl<BfResolvedArg>& argValues, BfTypedValue* argCascade)
|
||||
BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValue& inTarget, const BfTypedValue& origTarget, BfMethodDef* methodDef, BfModuleMethodInstance moduleMethodInstance, BfCreateCallFlags callFlags, SizedArrayImpl<BfResolvedArg>& argValues, BfTypedValue* argCascade)
|
||||
{
|
||||
bool bypassVirtual = (callFlags & BfCreateFallFlags_BypassVirtual) != 0;
|
||||
bool skipThis = (callFlags & BfCreateFallFlags_SkipThis) != 0;;
|
||||
bool bypassVirtual = (callFlags & BfCreateCallFlags_BypassVirtual) != 0;
|
||||
bool skipThis = (callFlags & BfCreateCallFlags_SkipThis) != 0;;
|
||||
|
||||
static int sCallIdx = 0;
|
||||
if (!mModule->mCompiler->mIsResolveOnly)
|
||||
|
@ -7050,7 +7055,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValu
|
|||
refNode = targetSrc;
|
||||
|
||||
if ((wantType->IsRef()) && (!argValue.mType->IsRef()) &&
|
||||
(((callFlags & BfCreateFallFlags_AllowImplicitRef) != 0) || (wantType->IsIn())))
|
||||
(((callFlags & BfCreateCallFlags_AllowImplicitRef) != 0) || (wantType->IsIn())))
|
||||
argValue = mModule->ToRef(argValue, (BfRefType*)wantType);
|
||||
|
||||
if (mModule->mCurMethodState != NULL)
|
||||
|
@ -7277,8 +7282,12 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValu
|
|||
return BfTypedValue();
|
||||
}
|
||||
|
||||
BfCreateCallFlags physCallFlags = BfCreateCallFlags_None;
|
||||
if ((origTarget.mType != NULL) && (origTarget.mType->IsGenericParam()))
|
||||
physCallFlags = (BfCreateCallFlags)(physCallFlags | BfCreateCallFlags_GenericParamThis);
|
||||
|
||||
auto func = moduleMethodInstance.mFunc;
|
||||
BfTypedValue callResult = CreateCall(targetSrc, methodInstance, func, bypassVirtual, irArgs);
|
||||
BfTypedValue callResult = CreateCall(targetSrc, methodInstance, func, bypassVirtual, irArgs, NULL, physCallFlags);
|
||||
|
||||
// This gets triggered for non-sret (ie: comptime) composite returns so they aren't considered readonly
|
||||
if ((callResult.mKind == BfTypedValueKind_Value) && (!callResult.mValue.IsConst()) &&
|
||||
|
@ -7480,7 +7489,7 @@ BfTypedValue BfExprEvaluator::MatchConstructor(BfAstNode* targetSrc, BfMethodBou
|
|||
if (isFailurePass)
|
||||
mModule->Fail(StrFormat("'%s' is inaccessible due to its protection level", mModule->MethodToString(moduleMethodInstance.mMethodInstance).c_str()), targetSrc);
|
||||
prevBindResult.Restore();
|
||||
return CreateCall(methodMatcher.mTargetSrc, target, BfTypedValue(), methodMatcher.mBestMethodDef, moduleMethodInstance, BfCreateFallFlags_None, methodMatcher.mArguments);
|
||||
return CreateCall(methodMatcher.mTargetSrc, target, BfTypedValue(), methodMatcher.mBestMethodDef, moduleMethodInstance, BfCreateCallFlags_None, methodMatcher.mArguments);
|
||||
}
|
||||
|
||||
static int sInvocationIdx = 0;
|
||||
|
@ -9155,11 +9164,11 @@ BfTypedValue BfExprEvaluator::MatchMethod(BfAstNode* targetSrc, BfMethodBoundExp
|
|||
mModule->Fail(StrFormat("Method '%s' can only be invoked at comptime. Consider adding [Comptime] to the current method.", mModule->MethodToString(moduleMethodInstance.mMethodInstance).c_str()), targetSrc);
|
||||
}
|
||||
|
||||
BfCreateFallFlags subCallFlags = BfCreateFallFlags_None;
|
||||
BfCreateCallFlags subCallFlags = BfCreateCallFlags_None;
|
||||
if (bypassVirtual)
|
||||
subCallFlags = (BfCreateFallFlags)(subCallFlags | BfCreateFallFlags_BypassVirtual);
|
||||
subCallFlags = (BfCreateCallFlags)(subCallFlags | BfCreateCallFlags_BypassVirtual);
|
||||
if (skipThis)
|
||||
subCallFlags = (BfCreateFallFlags)(subCallFlags | BfCreateFallFlags_SkipThis);
|
||||
subCallFlags = (BfCreateCallFlags)(subCallFlags | BfCreateCallFlags_SkipThis);
|
||||
result = CreateCall(targetSrc, callTarget, origTarget, methodDef, moduleMethodInstance, subCallFlags, argValues.mResolvedArgs, &argCascade);
|
||||
}
|
||||
|
||||
|
@ -9720,13 +9729,19 @@ void BfExprEvaluator::LookupQualifiedStaticField(BfAstNode* nameNode, BfIdentifi
|
|||
{
|
||||
mResult = LookupField(nameRight, BfTypedValue(genericParamInstance->mTypeConstraint), findName);
|
||||
if ((mResult) || (mPropDef != NULL))
|
||||
{
|
||||
mOrigPropTarget = lookupType;
|
||||
return;
|
||||
}
|
||||
}
|
||||
for (auto constraint : genericParamInstance->mInterfaceConstraints)
|
||||
{
|
||||
mResult = LookupField(nameRight, BfTypedValue(constraint), findName);
|
||||
if ((mResult) || (mPropDef != NULL))
|
||||
{
|
||||
mOrigPropTarget = lookupType;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -17059,7 +17074,10 @@ BfTypedValue BfExprEvaluator::GetResult(bool clearResult, bool resolveGenericTyp
|
|||
}
|
||||
}
|
||||
else
|
||||
mResult = CreateCall(mPropSrc, methodInstance.mMethodInstance, methodInstance.mFunc, mPropDefBypassVirtual, args);
|
||||
{
|
||||
BfCreateCallFlags callFlags = mOrigPropTarget.mType->IsGenericParam() ? BfCreateCallFlags_GenericParamThis : BfCreateCallFlags_None;
|
||||
mResult = CreateCall(mPropSrc, methodInstance.mMethodInstance, methodInstance.mFunc, mPropDefBypassVirtual, args, NULL, callFlags);
|
||||
}
|
||||
if (mResult.mType != NULL)
|
||||
{
|
||||
if ((mResult.mType->IsVar()) && (mModule->mCompiler->mIsResolveOnly))
|
||||
|
@ -21817,7 +21835,7 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod
|
|||
argValues.push_back(resolvedArg);
|
||||
resolvedArg.mTypedValue = rightValue;
|
||||
argValues.push_back(resolvedArg);
|
||||
mResult = CreateCall(opToken, BfTypedValue(), BfTypedValue(), moduleMethodInstance.mMethodInstance->mMethodDef, moduleMethodInstance, BfCreateFallFlags_None, argValues);
|
||||
mResult = CreateCall(opToken, BfTypedValue(), BfTypedValue(), moduleMethodInstance.mMethodInstance->mMethodDef, moduleMethodInstance, BfCreateCallFlags_None, argValues);
|
||||
if ((mResult) &&
|
||||
((binaryOp == BfBinaryOp_InEquality) || (binaryOp == BfBinaryOp_StrictInEquality)))
|
||||
mResult.mValue = mModule->mBfIRBuilder->CreateNot(mResult.mValue);
|
||||
|
|
|
@ -41,12 +41,14 @@ enum BfResolveArgFlags
|
|||
BfResolveArgFlag_FromGenericParam = 2
|
||||
};
|
||||
|
||||
enum BfCreateFallFlags
|
||||
enum BfCreateCallFlags
|
||||
{
|
||||
BfCreateFallFlags_None,
|
||||
BfCreateFallFlags_BypassVirtual = 1,
|
||||
BfCreateFallFlags_SkipThis = 2,
|
||||
BfCreateFallFlags_AllowImplicitRef = 4
|
||||
BfCreateCallFlags_None,
|
||||
BfCreateCallFlags_BypassVirtual = 1,
|
||||
BfCreateCallFlags_SkipThis = 2,
|
||||
BfCreateCallFlags_AllowImplicitRef = 4,
|
||||
BfCreateCallFlags_TailCall = 8,
|
||||
BfCreateCallFlags_GenericParamThis = 0x10
|
||||
};
|
||||
|
||||
class BfResolvedArg
|
||||
|
@ -444,8 +446,8 @@ public:
|
|||
BfTypedValue LookupIdentifier(BfIdentifierNode* identifierNode, bool ignoreInitialError = false, bool* hadError = NULL);
|
||||
void AddCallDependencies(BfMethodInstance* methodInstance);
|
||||
void PerformCallChecks(BfMethodInstance* methodInstance, BfAstNode* targetSrc);
|
||||
BfTypedValue CreateCall(BfAstNode* targetSrc, BfMethodInstance* methodInstance, BfIRValue func, bool bypassVirtual, SizedArrayImpl<BfIRValue>& irArgs, BfTypedValue* sret = NULL, bool isTailCall = false);
|
||||
BfTypedValue CreateCall(BfAstNode* targetSrc, const BfTypedValue& target, const BfTypedValue& origTarget, BfMethodDef* methodDef, BfModuleMethodInstance methodInstance, BfCreateFallFlags callFlags, SizedArrayImpl<BfResolvedArg>& argValues, BfTypedValue* argCascade = NULL);
|
||||
BfTypedValue CreateCall(BfAstNode* targetSrc, BfMethodInstance* methodInstance, BfIRValue func, bool bypassVirtual, SizedArrayImpl<BfIRValue>& irArgs, BfTypedValue* sret = NULL, BfCreateCallFlags callFlags = BfCreateCallFlags_None);
|
||||
BfTypedValue CreateCall(BfAstNode* targetSrc, const BfTypedValue& target, const BfTypedValue& origTarget, BfMethodDef* methodDef, BfModuleMethodInstance methodInstance, BfCreateCallFlags callFlags, SizedArrayImpl<BfResolvedArg>& argValues, BfTypedValue* argCascade = NULL);
|
||||
BfTypedValue CreateCall(BfMethodMatcher* methodMatcher, BfTypedValue target);
|
||||
void MakeBaseConcrete(BfTypedValue& typedValue);
|
||||
void SplatArgs(BfTypedValue value, SizedArrayImpl<BfIRValue>& irArgs);
|
||||
|
|
|
@ -19587,14 +19587,14 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup)
|
|||
mBfIRBuilder->PopulateType(methodInstance->mReturnType);
|
||||
auto returnType = BfTypedValue(mBfIRBuilder->GetArgument(methodInstance->GetStructRetIdx()), methodInstance->mReturnType, true);
|
||||
exprEvaluator.mReceivingValue = &returnType;
|
||||
auto retVal = exprEvaluator.CreateCall(NULL, innerMethodInstance.mMethodInstance, innerMethodInstance.mFunc, true, innerParams, NULL, true);
|
||||
auto retVal = exprEvaluator.CreateCall(NULL, innerMethodInstance.mMethodInstance, innerMethodInstance.mFunc, true, innerParams, NULL, BfCreateCallFlags_TailCall);
|
||||
BF_ASSERT(exprEvaluator.mReceivingValue == NULL); // Ensure it was actually used
|
||||
mBfIRBuilder->CreateRetVoid();
|
||||
}
|
||||
else
|
||||
{
|
||||
mBfIRBuilder->PopulateType(methodInstance->mReturnType);
|
||||
auto retVal = exprEvaluator.CreateCall(NULL, innerMethodInstance.mMethodInstance, innerMethodInstance.mFunc, true, innerParams, NULL, true);
|
||||
auto retVal = exprEvaluator.CreateCall(NULL, innerMethodInstance.mMethodInstance, innerMethodInstance.mFunc, true, innerParams, NULL, BfCreateCallFlags_TailCall);
|
||||
if (mCurMethodInstance->mReturnType->IsValueType())
|
||||
retVal = LoadValue(retVal);
|
||||
CreateReturn(retVal.mValue);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue