1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-08 19:48:20 +02:00

var-return support for const eval methods

This commit is contained in:
Brian Fiete 2020-12-30 13:24:13 -08:00
parent 585e2575e8
commit 706fe9e04b
15 changed files with 292 additions and 60 deletions

View file

@ -83,6 +83,7 @@ static CeOpInfo gOpInfo[] =
{
{"InvalidOp"},
{"Ret"},
{"SetRet", CEOI_None, CEOI_IMM32},
{"Jmp", CEOI_None, CEOI_JMPREL},
{"JmpIf", CEOI_None, CEOI_JMPREL, CEOI_FrameRef},
{"JmpIfNot", CEOI_None, CEOI_JMPREL, CEOI_FrameRef},
@ -1123,13 +1124,11 @@ void CeBuilder::HandleParams()
int frameOffset = 0;
if (retType->mSize > 0)
if (mCeFunction->mMaxReturnSize > 0)
{
mReturnVal.mKind = CeOperandKind_AllocaAddr;
mReturnVal.mFrameOfs = frameOffset;
mReturnVal.mType = retType;
frameOffset += retType->mSize;
frameOffset += mCeFunction->mMaxReturnSize;
}
int paramOfs = 0;
@ -1157,6 +1156,7 @@ void CeBuilder::HandleParams()
void CeBuilder::Build()
{
auto irCodeGen = mCeMachine->mCeModule->mBfIRBuilder->mBeIRCodeGen;
auto irBuilder = mCeMachine->mCeModule->mBfIRBuilder;
auto beModule = irCodeGen->mBeModule;
mCeFunction->mFailed = true;
@ -1168,16 +1168,18 @@ void CeBuilder::Build()
auto methodDef = methodInstance->mMethodDef;
BfMethodInstance dupMethodInstance;
dupMethodInstance.CopyFrom(methodInstance);
//dupMethodInstance.mIRFunction = workItem.mFunc;
dupMethodInstance.CopyFrom(methodInstance);
dupMethodInstance.mIsReified = true;
dupMethodInstance.mInCEMachine = false; // Only have the original one
int startFunctionCount = (int)beModule->mFunctions.size();
//int startGlobalVariableCount = (int)beModule->mGlobalVariables.size();
mCeMachine->mCeModule->mHadBuildError = false;
auto irState = irBuilder->GetState();
auto beState = irCodeGen->GetState();
mCeMachine->mCeModule->ProcessMethod(&dupMethodInstance, true);
irCodeGen->SetState(beState);
irBuilder->SetState(irState);
if (!dupMethodInstance.mIRFunction)
{
@ -1197,6 +1199,7 @@ void CeBuilder::Build()
continue;
CeFunction* innerFunction = new CeFunction();
innerFunction->mIsVarReturn = beFunction->mIsVarReturn;
innerFunction->mCeInnerFunctionInfo = new CeInnerFunctionInfo();
innerFunction->mCeInnerFunctionInfo->mName = beFunction->mName;
innerFunction->mCeInnerFunctionInfo->mBeFunction = beFunction;
@ -1294,6 +1297,17 @@ void CeBuilder::Build()
}
}
break;
case BeRetInst::TypeId:
case BeSetRetInst::TypeId:
{
auto castedInst = (BeRetInst*)inst;
if (castedInst->mRetValue != NULL)
{
auto retType = castedInst->mRetValue->GetType();
mCeFunction->mMaxReturnSize = BF_MAX(retType->mSize, mCeFunction->mMaxReturnSize);
}
}
break;
}
}
}
@ -1788,18 +1802,27 @@ void CeBuilder::Build()
}
break;
case BeRetInst::TypeId:
{
case BeSetRetInst::TypeId:
{
auto castedInst = (BeRetInst*)inst;
if (castedInst->mRetValue != NULL)
{
auto mcVal = GetOperand(castedInst->mRetValue);
auto mcVal = GetOperand(castedInst->mRetValue);
BF_ASSERT(mReturnVal.mKind == CeOperandKind_AllocaAddr);
EmitSizedOp(CeOp_Move_8, mcVal, NULL, true);
Emit((int32)mReturnVal.mFrameOfs);
Emit((int32)mReturnVal.mFrameOfs);
}
if (instType == BeRetInst::TypeId)
Emit(CeOp_Ret);
else
{
auto setRetInst = (BeSetRetInst*)inst;
Emit(CeOp_SetRetType);
Emit((int32)setRetInst->mReturnTypeId);
}
Emit(CeOp_Ret);
}
break;
break;
case BeCmpInst::TypeId:
{
auto castedInst = (BeCmpInst*)inst;
@ -3483,6 +3506,9 @@ BfIRValue CeMachine::CreateConstant(BfModule* module, uint8* ptr, BfType* bfType
{
auto typeInst = bfType->ToTypeInstance();
if (typeInst->mIsUnion)
return BfIRValue();
uint8* instData = ptr;
// if ((typeInst->IsObject()) && (!isBaseType))
// {
@ -3744,11 +3770,12 @@ BfIRValue CeMachine::CreateConstant(BfModule* module, uint8* ptr, BfType* bfType
instPtr = &ceFunction->mCode[0]; \
CE_CHECKSTACK();
bool CeMachine::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* startFramePtr)
bool CeMachine::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* startFramePtr, BfType*& returnType)
{
mExecuteId++;
CeFunction* ceFunction = startFunction;
returnType = startFunction->mMethodInstance->mReturnType;
uint8* memStart = &mMemory[0];
int memSize = mMemory.mSize;
uint8* instPtr = (ceFunction->mCode.IsEmpty()) ? NULL : &ceFunction->mCode[0];
@ -3758,11 +3785,11 @@ bool CeMachine::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
volatile bool* cancelPtr = &mCompiler->mCanceling;
auto _GetCurFrame = [&]()
{
CeFrame ceFrame;
ceFrame.mFunction = ceFunction;
ceFrame.mReturnType = returnType;
ceFrame.mFrameAddr = framePtr - memStart;
ceFrame.mStackAddr = stackPtr - memStart;
ceFrame.mInstPtr = instPtr;
@ -4026,6 +4053,7 @@ bool CeMachine::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
Fail(_GetCurFrame(), StrFormat("Unable to invoke extern method '%s'", mCeModule->MethodToString(checkFunction->mMethodInstance).c_str()));
return false;
}
if (!checkFunction->mFailed)
return true;
@ -4070,10 +4098,18 @@ bool CeMachine::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
instPtr = ceFrame.mInstPtr;
stackPtr = memStart + ceFrame.mStackAddr;
framePtr = memStart + ceFrame.mFrameAddr;
returnType = ceFrame.mReturnType;
mCallStack.pop_back();
}
break;
case CeOp_SetRetType:
{
int typeId = CE_GETINST(int32);
returnType = GetBfType(typeId);
BF_ASSERT(returnType != NULL);
}
break;
case CeOp_Jmp:
{
auto relOfs = CE_GETINST(int32);
@ -4666,6 +4702,8 @@ bool CeMachine::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
bool handled = false;
if (!_CheckFunction(callFunction, handled))
return false;
if (callFunction->mIsVarReturn)
_Fail("Illegal call to method with 'var' return.");
if (handled)
break;
@ -5284,14 +5322,17 @@ void CeMachine::PrepareFunction(CeFunction* ceFunction, CeBuilder* parentBuilder
BF_ASSERT(!ceFunction->mInitialized);
ceFunction->mInitialized = true;
ceFunction->mGenerating = true;
CeBuilder ceBuilder;
ceBuilder.mParentBuilder = parentBuilder;
ceBuilder.mPtrSize = mCeModule->mCompiler->mSystem->mPtrSize;
ceBuilder.mCeMachine = this;
ceBuilder.mCeFunction = ceFunction;
ceBuilder.mCeFunction = ceFunction;
ceBuilder.Build();
ceFunction->mGenerating = false;
/*if (!ceFunction->mCode.IsEmpty())
{
CeDumpContext dumpCtx;
@ -5375,6 +5416,7 @@ CeFunction* CeMachine::GetFunction(BfMethodInstance* methodInstance, BfIRValue f
BF_ASSERT(ceFunctionInfo->mCeFunction == NULL);
ceFunction = new CeFunction();
ceFunction->mIsVarReturn = methodInstance->mReturnType->IsVar();
ceFunction->mCeFunctionInfo = ceFunctionInfo;
ceFunction->mMethodInstance = methodInstance;
@ -5441,7 +5483,7 @@ BfTypedValue CeMachine::Call(BfAstNode* targetSrc, BfModule* module, BfMethodIns
SetAndRestoreValue<BfAstNode*> prevTargetSrc(mCurTargetSrc, targetSrc);
SetAndRestoreValue<BfModule*> prevModule(mCurModule, module);
SetAndRestoreValue<BfMethodInstance*> prevMethodInstance(mCurMethodInstance, methodInstance);
SetAndRestoreValue<BfType*> prevExpectingType(mCurExpectingType, expectingType);
SetAndRestoreValue<BfType*> prevExpectingType(mCurExpectingType, expectingType);
// Reentrancy may occur as methods need defining
SetAndRestoreValue<BfMethodState*> prevMethodStateInConstEval(module->mCurMethodState, NULL);
@ -5453,7 +5495,7 @@ BfTypedValue CeMachine::Call(BfAstNode* targetSrc, BfModule* module, BfMethodIns
Fail("Non-constant append alloc");
return BfTypedValue();
}
}
}
int thisArgIdx = -1;
int appendAllocIdx = -1;
@ -5505,6 +5547,13 @@ BfTypedValue CeMachine::Call(BfAstNode* targetSrc, BfModule* module, BfMethodIns
bool added = false;
CeFunction* ceFunction = GetFunction(methodInstance, BfIRValue(), added);
if (ceFunction->mGenerating)
{
Fail("Recursive var-inference");
return BfTypedValue();
}
if (!ceFunction->mInitialized)
PrepareFunction(ceFunction, NULL);
@ -5631,15 +5680,15 @@ BfTypedValue CeMachine::Call(BfAstNode* targetSrc, BfModule* module, BfMethodIns
}
addr_ce retAddr = 0;
auto returnType = methodInstance->mReturnType;
if (!returnType->IsValuelessType())
if (ceFunction->mMaxReturnSize > 0)
{
int retSize = methodInstance->mReturnType->mSize;
int retSize = ceFunction->mMaxReturnSize;
stackPtr -= retSize;
retAddr = stackPtr - memStart;
}
bool success = Execute(ceFunction, stackPtr - ceFunction->mFrameSize, stackPtr);
BfType* returnType = NULL;
bool success = Execute(ceFunction, stackPtr - ceFunction->mFrameSize, stackPtr, returnType);
memStart = &mMemory[0];
addr_ce retInstAddr = retAddr;