mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-14 14:24:10 +02:00
Fixed argument cascades with ReturnValueDiscarded
This commit is contained in:
parent
8ceb7bf183
commit
bd57172996
3 changed files with 78 additions and 23 deletions
|
@ -5568,8 +5568,8 @@ BfTypedValue BfExprEvaluator::CreateCall(BfMethodMatcher* methodMatcher, BfTyped
|
||||||
}
|
}
|
||||||
|
|
||||||
PerformCallChecks(moduleMethodInstance.mMethodInstance, methodMatcher->mTargetSrc);
|
PerformCallChecks(moduleMethodInstance.mMethodInstance, methodMatcher->mTargetSrc);
|
||||||
|
|
||||||
return CreateCall(methodMatcher->mTargetSrc, target, BfTypedValue(), methodMatcher->mBestMethodDef, moduleMethodInstance, false, methodMatcher->mArguments);
|
return CreateCall(methodMatcher->mTargetSrc, target, BfTypedValue(), methodMatcher->mBestMethodDef, moduleMethodInstance, false, methodMatcher->mArguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BfExprEvaluator::MakeBaseConcrete(BfTypedValue& typedValue)
|
void BfExprEvaluator::MakeBaseConcrete(BfTypedValue& typedValue)
|
||||||
|
@ -5873,7 +5873,7 @@ void BfExprEvaluator::AddCallDependencies(BfMethodInstance* methodInstance)
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: delete argumentsZ
|
//TODO: delete argumentsZ
|
||||||
BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValue& inTarget, const BfTypedValue& origTarget, BfMethodDef* methodDef, BfModuleMethodInstance moduleMethodInstance, bool bypassVirtual, SizedArrayImpl<BfResolvedArg>& argValues, bool skipThis)
|
BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValue& inTarget, const BfTypedValue& origTarget, BfMethodDef* methodDef, BfModuleMethodInstance moduleMethodInstance, bool bypassVirtual, SizedArrayImpl<BfResolvedArg>& argValues, BfTypedValue* argCascade, bool skipThis)
|
||||||
{
|
{
|
||||||
static int sCallIdx = 0;
|
static int sCallIdx = 0;
|
||||||
if (!mModule->mCompiler->mIsResolveOnly)
|
if (!mModule->mCompiler->mIsResolveOnly)
|
||||||
|
@ -6617,7 +6617,10 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValu
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((argExprIdx != -1) && (argExprIdx < (int)argValues.size()) && ((argValues[argExprIdx].mArgFlags & BfArgFlag_Cascade) != 0))
|
if ((argExprIdx != -1) && (argExprIdx < (int)argValues.size()) && ((argValues[argExprIdx].mArgFlags & BfArgFlag_Cascade) != 0))
|
||||||
|
{
|
||||||
|
mUsedAsStatement = true;
|
||||||
argCascades.Add(argValue);
|
argCascades.Add(argValue);
|
||||||
|
}
|
||||||
|
|
||||||
if (expandedParamsArray)
|
if (expandedParamsArray)
|
||||||
{
|
{
|
||||||
|
@ -6787,9 +6790,17 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValu
|
||||||
BfTypedValue callResult = CreateCall(targetSrc, methodInstance, func, bypassVirtual, irArgs);
|
BfTypedValue callResult = CreateCall(targetSrc, methodInstance, func, bypassVirtual, irArgs);
|
||||||
|
|
||||||
if (argCascades.mSize == 1)
|
if (argCascades.mSize == 1)
|
||||||
return argCascades[0];
|
{
|
||||||
|
if (argCascade == NULL)
|
||||||
|
return argCascades[0];
|
||||||
|
*argCascade = argCascades[0];
|
||||||
|
}
|
||||||
if (argCascades.mSize > 1)
|
if (argCascades.mSize > 1)
|
||||||
return mModule->CreateTuple(argCascades, {});
|
{
|
||||||
|
if (argCascade == NULL)
|
||||||
|
return mModule->CreateTuple(argCascades, {});
|
||||||
|
*argCascade = mModule->CreateTuple(argCascades, {});
|
||||||
|
}
|
||||||
|
|
||||||
return callResult;
|
return callResult;
|
||||||
}
|
}
|
||||||
|
@ -8471,6 +8482,7 @@ BfTypedValue BfExprEvaluator::MatchMethod(BfAstNode* targetSrc, BfMethodBoundExp
|
||||||
|
|
||||||
|
|
||||||
BfTypedValue result;
|
BfTypedValue result;
|
||||||
|
BfTypedValue argCascade;
|
||||||
|
|
||||||
//
|
//
|
||||||
{
|
{
|
||||||
|
@ -8486,26 +8498,13 @@ BfTypedValue BfExprEvaluator::MatchMethod(BfAstNode* targetSrc, BfMethodBoundExp
|
||||||
mBfEvalExprFlags = (BfEvalExprFlags)(mBfEvalExprFlags | BfEvalExprFlags_ConstEval);
|
mBfEvalExprFlags = (BfEvalExprFlags)(mBfEvalExprFlags | BfEvalExprFlags_ConstEval);
|
||||||
}
|
}
|
||||||
|
|
||||||
result = CreateCall(targetSrc, callTarget, origTarget, methodDef, moduleMethodInstance, bypassVirtual, argValues.mResolvedArgs, skipThis);
|
result = CreateCall(targetSrc, callTarget, origTarget, methodDef, moduleMethodInstance, bypassVirtual, argValues.mResolvedArgs, &argCascade, skipThis);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result)
|
if (result)
|
||||||
{
|
{
|
||||||
if (result.mType->IsRef())
|
if (result.mType->IsRef())
|
||||||
result = mModule->RemoveRef(result);
|
result = mModule->RemoveRef(result);
|
||||||
if (result.mType->IsSelf())
|
|
||||||
{
|
|
||||||
if (methodMatcher.mSelfType != NULL)
|
|
||||||
{
|
|
||||||
BF_ASSERT(mModule->IsInGeneric());
|
|
||||||
result = mModule->GetDefaultTypedValue(methodMatcher.mSelfType);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Will be an error
|
|
||||||
result = mModule->GetDefaultTypedValue(methodMatcher.mBestMethodTypeInstance);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PerformCallChecks(moduleMethodInstance.mMethodInstance, targetSrc);
|
PerformCallChecks(moduleMethodInstance.mMethodInstance, targetSrc);
|
||||||
|
@ -8566,6 +8565,30 @@ BfTypedValue BfExprEvaluator::MatchMethod(BfAstNode* targetSrc, BfMethodBoundExp
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (argCascade)
|
||||||
|
{
|
||||||
|
if (argCascade.mType->IsRef())
|
||||||
|
argCascade = mModule->RemoveRef(argCascade);
|
||||||
|
result = argCascade;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result)
|
||||||
|
{
|
||||||
|
if (result.mType->IsSelf())
|
||||||
|
{
|
||||||
|
if (methodMatcher.mSelfType != NULL)
|
||||||
|
{
|
||||||
|
BF_ASSERT(mModule->IsInGeneric());
|
||||||
|
result = mModule->GetDefaultTypedValue(methodMatcher.mSelfType);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Will be an error
|
||||||
|
result = mModule->GetDefaultTypedValue(methodMatcher.mBestMethodTypeInstance);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -431,7 +431,7 @@ public:
|
||||||
void AddCallDependencies(BfMethodInstance* methodInstance);
|
void AddCallDependencies(BfMethodInstance* methodInstance);
|
||||||
void PerformCallChecks(BfMethodInstance* methodInstance, BfAstNode* targetSrc);
|
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, 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, bool bypassVirtual, SizedArrayImpl<BfResolvedArg>& argValues, bool skipThis = false);
|
BfTypedValue CreateCall(BfAstNode* targetSrc, const BfTypedValue& target, const BfTypedValue& origTarget, BfMethodDef* methodDef, BfModuleMethodInstance methodInstance, bool bypassVirtual, SizedArrayImpl<BfResolvedArg>& argValues, BfTypedValue* argCascade = NULL, bool skipThis = false);
|
||||||
BfTypedValue CreateCall(BfMethodMatcher* methodMatcher, BfTypedValue target);
|
BfTypedValue CreateCall(BfMethodMatcher* methodMatcher, BfTypedValue target);
|
||||||
void MakeBaseConcrete(BfTypedValue& typedValue);
|
void MakeBaseConcrete(BfTypedValue& typedValue);
|
||||||
void SplatArgs(BfTypedValue value, SizedArrayImpl<BfIRValue>& irArgs);
|
void SplatArgs(BfTypedValue value, SizedArrayImpl<BfIRValue>& irArgs);
|
||||||
|
|
|
@ -4,27 +4,59 @@ namespace Tests
|
||||||
{
|
{
|
||||||
class Cascades
|
class Cascades
|
||||||
{
|
{
|
||||||
public static void MethodA(int a, float b)
|
struct StructA
|
||||||
{
|
{
|
||||||
|
public static int sDiscardCount;
|
||||||
|
public void ReturnValueDiscarded()
|
||||||
|
{
|
||||||
|
sDiscardCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void HandleResult()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public StructA Method0(int a)
|
||||||
|
{
|
||||||
|
return .();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void MethodB(int a, out float b)
|
static StructA MethodA(int a, float b)
|
||||||
|
{
|
||||||
|
return .();
|
||||||
|
}
|
||||||
|
|
||||||
|
static StructA MethodB(int a, out float b)
|
||||||
{
|
{
|
||||||
b = 100;
|
b = 100;
|
||||||
|
return .();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public static void TestBasics()
|
public static void TestBasics()
|
||||||
{
|
{
|
||||||
|
MethodA(1, 1.2f);
|
||||||
|
Test.Assert(StructA.sDiscardCount == 1);
|
||||||
|
|
||||||
|
StructA sa = .();
|
||||||
|
sa.Method0(1)..Method0(2).HandleResult();
|
||||||
|
Test.Assert(StructA.sDiscardCount == 2);
|
||||||
|
|
||||||
int a = MethodA(.. 12, 2.3f);
|
int a = MethodA(.. 12, 2.3f);
|
||||||
|
Test.Assert(StructA.sDiscardCount == 3);
|
||||||
Test.Assert(a == 12);
|
Test.Assert(a == 12);
|
||||||
|
|
||||||
var (b, c) = MethodA(.. 12, .. 2.3f);
|
var (b, c) = MethodA(.. 12, .. 2.3f);
|
||||||
|
Test.Assert(StructA.sDiscardCount == 4);
|
||||||
Test.Assert(b == 12);
|
Test.Assert(b == 12);
|
||||||
Test.Assert(c == 2.3f);
|
Test.Assert(c == 2.3f);
|
||||||
var d = MethodA(.. 12, .. 2.3f);
|
var d = MethodA(.. 12, .. 2.3f);
|
||||||
|
Test.Assert(StructA.sDiscardCount == 5);
|
||||||
Test.Assert(d == (12, 2.3f));
|
Test.Assert(d == (12, 2.3f));
|
||||||
var f = ref MethodB(12, .. var e);
|
var f = ref MethodB(12, .. var e);
|
||||||
|
Test.Assert(StructA.sDiscardCount == 6);
|
||||||
e += 23;
|
e += 23;
|
||||||
Test.Assert(e == (int)123);
|
Test.Assert(e == (int)123);
|
||||||
Test.Assert(f == (int)123);
|
Test.Assert(f == (int)123);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue