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:
parent
585e2575e8
commit
706fe9e04b
15 changed files with 292 additions and 60 deletions
|
@ -379,9 +379,11 @@ BeType* BeIRCodeGen::GetBeType(BfTypeCode typeCode, bool& isSigned)
|
||||||
else
|
else
|
||||||
return llvm::Type::getInt64Ty(*mLLVMContext);*/
|
return llvm::Type::getInt64Ty(*mLLVMContext);*/
|
||||||
case BfTypeCode_Float:
|
case BfTypeCode_Float:
|
||||||
|
isSigned = true;
|
||||||
beTypeCode = BeTypeCode_Float;
|
beTypeCode = BeTypeCode_Float;
|
||||||
break;
|
break;
|
||||||
case BfTypeCode_Double:
|
case BfTypeCode_Double:
|
||||||
|
isSigned = true;
|
||||||
beTypeCode = BeTypeCode_Double;
|
beTypeCode = BeTypeCode_Double;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -2330,6 +2332,13 @@ void BeIRCodeGen::HandleNextCmd()
|
||||||
SetResult(curId, mBeModule->CreateRet(val));
|
SetResult(curId, mBeModule->CreateRet(val));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case BfIRCmd_CreateSetRet:
|
||||||
|
{
|
||||||
|
CMD_PARAM(BeValue*, val);
|
||||||
|
CMD_PARAM(int, returnTypeId);
|
||||||
|
SetResult(curId, mBeModule->CreateSetRet(val, returnTypeId));
|
||||||
|
}
|
||||||
|
break;
|
||||||
case BfIRCmd_CreateRetVoid:
|
case BfIRCmd_CreateRetVoid:
|
||||||
{
|
{
|
||||||
mBeModule->CreateRetVoid();
|
mBeModule->CreateRetVoid();
|
||||||
|
@ -2433,7 +2442,9 @@ void BeIRCodeGen::HandleNextCmd()
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (attribute == BFIRAttribute_AlwaysInline)
|
if (attribute == BfIRAttribute_VarRet)
|
||||||
|
func->mIsVarReturn = true;
|
||||||
|
else if (attribute == BFIRAttribute_AlwaysInline)
|
||||||
func->mAlwaysInline = true;
|
func->mAlwaysInline = true;
|
||||||
else if (attribute == BFIRAttribute_NoUnwind)
|
else if (attribute == BFIRAttribute_NoUnwind)
|
||||||
func->mNoUnwind = true;
|
func->mNoUnwind = true;
|
||||||
|
@ -3483,3 +3494,33 @@ BeType* BeIRCodeGen::GetBeTypeById(int id)
|
||||||
{
|
{
|
||||||
return GetTypeEntry(id).mBeType;
|
return GetTypeEntry(id).mBeType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BeState BeIRCodeGen::GetState()
|
||||||
|
{
|
||||||
|
BeState state;
|
||||||
|
state.mActiveFunction = mActiveFunction;
|
||||||
|
state.mSavedDebugLocs = mSavedDebugLocs;
|
||||||
|
state.mHasDebugLoc = mHasDebugLoc;
|
||||||
|
|
||||||
|
state.mActiveBlock = mBeModule->mActiveBlock;
|
||||||
|
state.mInsertPos = mBeModule->mInsertPos;
|
||||||
|
state.mCurDbgLoc = mBeModule->mCurDbgLoc;
|
||||||
|
state.mPrevDbgLocInline = mBeModule->mPrevDbgLocInline;
|
||||||
|
state.mLastDbgLoc = mBeModule->mLastDbgLoc;
|
||||||
|
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BeIRCodeGen::SetState(const BeState& state)
|
||||||
|
{
|
||||||
|
mActiveFunction = state.mActiveFunction;
|
||||||
|
mBeModule->mActiveFunction = mActiveFunction;
|
||||||
|
mSavedDebugLocs = state.mSavedDebugLocs;
|
||||||
|
mHasDebugLoc = state.mHasDebugLoc;
|
||||||
|
|
||||||
|
mBeModule->mActiveBlock = state.mActiveBlock;
|
||||||
|
mBeModule->mInsertPos = state.mInsertPos;
|
||||||
|
mBeModule->mCurDbgLoc = state.mCurDbgLoc;
|
||||||
|
mBeModule->mPrevDbgLocInline = state.mPrevDbgLocInline;
|
||||||
|
mBeModule->mLastDbgLoc = state.mLastDbgLoc;
|
||||||
|
}
|
||||||
|
|
|
@ -53,6 +53,19 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class BeState
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
BeFunction* mActiveFunction;
|
||||||
|
Array<BeDbgLoc*> mSavedDebugLocs;
|
||||||
|
bool mHasDebugLoc;
|
||||||
|
|
||||||
|
BeBlock* mActiveBlock;
|
||||||
|
int mInsertPos;
|
||||||
|
BeDbgLoc* mCurDbgLoc;
|
||||||
|
BeDbgLoc* mPrevDbgLocInline;
|
||||||
|
BeDbgLoc* mLastDbgLoc;
|
||||||
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class CmdParamVec : public SizedArray<T, 8>
|
class CmdParamVec : public SizedArray<T, 8>
|
||||||
|
@ -139,6 +152,9 @@ public:
|
||||||
BeMDNode* GetBeMetadata(int streamId);
|
BeMDNode* GetBeMetadata(int streamId);
|
||||||
|
|
||||||
BeType* GetBeTypeById(int id);
|
BeType* GetBeTypeById(int id);
|
||||||
|
|
||||||
|
BeState GetState();
|
||||||
|
void SetState(const BeState& state);
|
||||||
};
|
};
|
||||||
|
|
||||||
NS_BF_END
|
NS_BF_END
|
|
@ -2349,6 +2349,7 @@ String BeModule::ToString(BeFunction* wantFunc)
|
||||||
str += " void";
|
str += " void";
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
DISPLAY_INST2(BeSetRetInst, "setret", mRetValue, mReturnTypeId);
|
||||||
case BeCallInst::TypeId:
|
case BeCallInst::TypeId:
|
||||||
{
|
{
|
||||||
auto castedInst = (BeCallInst*)inst;
|
auto castedInst = (BeCallInst*)inst;
|
||||||
|
@ -3383,6 +3384,15 @@ BeRetInst* BeModule::CreateRet(BeValue* value)
|
||||||
return inst;
|
return inst;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BeSetRetInst* BeModule::CreateSetRet(BeValue* value, int returnTypeId)
|
||||||
|
{
|
||||||
|
auto inst = mAlloc.Alloc<BeSetRetInst>();
|
||||||
|
inst->mRetValue = value;
|
||||||
|
inst->mReturnTypeId = returnTypeId;
|
||||||
|
AddInst(inst);
|
||||||
|
return inst;
|
||||||
|
}
|
||||||
|
|
||||||
BeCallInst* BeModule::CreateCall(BeValue* func, const SizedArrayImpl<BeValue*>& args)
|
BeCallInst* BeModule::CreateCall(BeValue* func, const SizedArrayImpl<BeValue*>& args)
|
||||||
{
|
{
|
||||||
auto inst = mOwnedValues.Alloc<BeCallInst>();
|
auto inst = mOwnedValues.Alloc<BeCallInst>();
|
||||||
|
|
|
@ -518,6 +518,7 @@ public:
|
||||||
String mName;
|
String mName;
|
||||||
#endif
|
#endif
|
||||||
BfIRLinkageType mLinkageType;
|
BfIRLinkageType mLinkageType;
|
||||||
|
bool mIsVarReturn;
|
||||||
bool mAlwaysInline;
|
bool mAlwaysInline;
|
||||||
bool mNoUnwind;
|
bool mNoUnwind;
|
||||||
bool mUWTable;
|
bool mUWTable;
|
||||||
|
@ -539,6 +540,7 @@ public:
|
||||||
mLinkageType = BfIRLinkageType_External;
|
mLinkageType = BfIRLinkageType_External;
|
||||||
mModule = NULL;
|
mModule = NULL;
|
||||||
mDbgFunction = NULL;
|
mDbgFunction = NULL;
|
||||||
|
mIsVarReturn = false;
|
||||||
mAlwaysInline = false;
|
mAlwaysInline = false;
|
||||||
mDidInlinePass = false;
|
mDidInlinePass = false;
|
||||||
mNoUnwind = false;
|
mNoUnwind = false;
|
||||||
|
@ -1265,6 +1267,15 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class BeSetRetInst : public BeRetInst
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
BE_VALUE_TYPE(BeSetRetInst, BeRetInst);
|
||||||
|
|
||||||
|
public:
|
||||||
|
int32 mReturnTypeId;
|
||||||
|
};
|
||||||
|
|
||||||
class BeCallInst : public BeInst
|
class BeCallInst : public BeInst
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -2311,6 +2322,7 @@ public:
|
||||||
BeCondBrInst* CreateCondBr(BeValue* cond, BeBlock* trueBlock, BeBlock* falseBlock);
|
BeCondBrInst* CreateCondBr(BeValue* cond, BeBlock* trueBlock, BeBlock* falseBlock);
|
||||||
BeRetInst* CreateRetVoid();
|
BeRetInst* CreateRetVoid();
|
||||||
BeRetInst* CreateRet(BeValue* value);
|
BeRetInst* CreateRet(BeValue* value);
|
||||||
|
BeSetRetInst* CreateSetRet(BeValue* value, int returnTypeId);
|
||||||
BeCallInst* CreateCall(BeValue* func, const SizedArrayImpl<BeValue*>& args);
|
BeCallInst* CreateCall(BeValue* func, const SizedArrayImpl<BeValue*>& args);
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -5026,7 +5026,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance*
|
||||||
|
|
||||||
if (mModule->mCompiler->mCEMachine != NULL)
|
if (mModule->mCompiler->mCEMachine != NULL)
|
||||||
{
|
{
|
||||||
if (mModule->mIsConstModule)
|
if ((mModule->mIsConstModule) && (!methodInstance->mReturnType->IsVar()))
|
||||||
{
|
{
|
||||||
mModule->mCompiler->mCEMachine->QueueMethod(methodInstance, func);
|
mModule->mCompiler->mCEMachine->QueueMethod(methodInstance, func);
|
||||||
}
|
}
|
||||||
|
@ -5045,10 +5045,13 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance*
|
||||||
CeEvalFlags evalFlags = CeEvalFlags_None;
|
CeEvalFlags evalFlags = CeEvalFlags_None;
|
||||||
auto constRet = mModule->mCompiler->mCEMachine->Call(targetSrc, mModule, methodInstance, irArgs, evalFlags, mExpectingType);
|
auto constRet = mModule->mCompiler->mCEMachine->Call(targetSrc, mModule, methodInstance, irArgs, evalFlags, mExpectingType);
|
||||||
if (constRet)
|
if (constRet)
|
||||||
|
{
|
||||||
|
BF_ASSERT(!constRet.mType->IsVar());
|
||||||
return constRet;
|
return constRet;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!forceBind)
|
if (!forceBind)
|
||||||
{
|
{
|
||||||
|
|
|
@ -730,6 +730,13 @@ BfIRValue BfIRConstHolder::CreateConstStructZero(BfIRType aggType)
|
||||||
|
|
||||||
BfIRValue BfIRConstHolder::CreateConstAgg(BfIRType type, const BfSizedArray<BfIRValue>& values)
|
BfIRValue BfIRConstHolder::CreateConstAgg(BfIRType type, const BfSizedArray<BfIRValue>& values)
|
||||||
{
|
{
|
||||||
|
#ifdef _DEBUG
|
||||||
|
for (auto& val : values)
|
||||||
|
{
|
||||||
|
BF_ASSERT(val);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
BfConstantAgg* constant = mTempAlloc.Alloc<BfConstantAgg>();
|
BfConstantAgg* constant = mTempAlloc.Alloc<BfConstantAgg>();
|
||||||
constant->mConstType = BfConstType_Agg;
|
constant->mConstType = BfConstType_Agg;
|
||||||
constant->mType = type = type;
|
constant->mType = type = type;
|
||||||
|
@ -4766,6 +4773,13 @@ BfIRValue BfIRBuilder::CreateRet(BfIRValue val)
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BfIRValue BfIRBuilder::CreateSetRet(BfIRValue val, int returnTypeId)
|
||||||
|
{
|
||||||
|
BfIRValue retVal = WriteCmd(BfIRCmd_CreateSetRet, val, returnTypeId);
|
||||||
|
NEW_CMD_INSERTED;
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
void BfIRBuilder::CreateRetVoid()
|
void BfIRBuilder::CreateRetVoid()
|
||||||
{
|
{
|
||||||
WriteCmd(BfIRCmd_CreateRetVoid);
|
WriteCmd(BfIRCmd_CreateRetVoid);
|
||||||
|
@ -5391,4 +5405,22 @@ void BfIRBuilder::DbgCreateAnnotation(BfIRMDNode scope, const StringImpl& name,
|
||||||
NEW_CMD_INSERTED;
|
NEW_CMD_INSERTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BfIRState BfIRBuilder::GetState()
|
||||||
|
{
|
||||||
|
BfIRState state;
|
||||||
|
state.mActualInsertBlock = mActualInsertBlock;
|
||||||
|
state.mInsertBlock = mInsertBlock;
|
||||||
|
state.mActiveFunction = mActiveFunction;
|
||||||
|
state.mActiveFunctionHasBody = mActiveFunctionHasBody;
|
||||||
|
state.mSavedDebugLocs = mSavedDebugLocs;
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BfIRBuilder::SetState(const BfIRState& state)
|
||||||
|
{
|
||||||
|
mActualInsertBlock = state.mActualInsertBlock;
|
||||||
|
mInsertBlock = state.mInsertBlock;
|
||||||
|
mActiveFunction = state.mActiveFunction;
|
||||||
|
mActiveFunctionHasBody = state.mActiveFunctionHasBody;
|
||||||
|
mSavedDebugLocs = state.mSavedDebugLocs;
|
||||||
|
}
|
||||||
|
|
|
@ -270,6 +270,7 @@ enum BfIRCmd : uint8
|
||||||
BfIRCmd_SetTailCall,
|
BfIRCmd_SetTailCall,
|
||||||
BfIRCmd_SetCallAttribute,
|
BfIRCmd_SetCallAttribute,
|
||||||
BfIRCmd_CreateRet,
|
BfIRCmd_CreateRet,
|
||||||
|
BfIRCmd_CreateSetRet,
|
||||||
BfIRCmd_CreateRetVoid,
|
BfIRCmd_CreateRetVoid,
|
||||||
BfIRCmd_CreateUnreachable,
|
BfIRCmd_CreateUnreachable,
|
||||||
BfIRCmd_Call_AddAttribute,
|
BfIRCmd_Call_AddAttribute,
|
||||||
|
@ -627,6 +628,7 @@ enum BfIRAttribute
|
||||||
BfIRAttribute_NoAlias,
|
BfIRAttribute_NoAlias,
|
||||||
BfIRAttribute_NoCapture,
|
BfIRAttribute_NoCapture,
|
||||||
BfIRAttribute_StructRet,
|
BfIRAttribute_StructRet,
|
||||||
|
BfIRAttribute_VarRet,
|
||||||
BfIRAttribute_ZExt,
|
BfIRAttribute_ZExt,
|
||||||
BfIRAttribute_ByVal,
|
BfIRAttribute_ByVal,
|
||||||
BfIRAttribute_Dereferencable,
|
BfIRAttribute_Dereferencable,
|
||||||
|
@ -916,6 +918,15 @@ enum BfIRPopulateType
|
||||||
BfIRPopulateType_Full_ForceDefinition
|
BfIRPopulateType_Full_ForceDefinition
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct BfIRState
|
||||||
|
{
|
||||||
|
BfIRBlock mActualInsertBlock; // Only when not ignoring writes
|
||||||
|
BfIRBlock mInsertBlock;
|
||||||
|
BfIRFunction mActiveFunction;
|
||||||
|
bool mActiveFunctionHasBody;
|
||||||
|
Array<BfFilePosition> mSavedDebugLocs;
|
||||||
|
};
|
||||||
|
|
||||||
class BfIRBuilder : public BfIRConstHolder
|
class BfIRBuilder : public BfIRConstHolder
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -1227,6 +1238,7 @@ public:
|
||||||
void SetTailCall(BfIRValue callInst);
|
void SetTailCall(BfIRValue callInst);
|
||||||
void SetCallAttribute(BfIRValue callInst, int paramIdx, BfIRAttribute attribute);
|
void SetCallAttribute(BfIRValue callInst, int paramIdx, BfIRAttribute attribute);
|
||||||
BfIRValue CreateRet(BfIRValue val);
|
BfIRValue CreateRet(BfIRValue val);
|
||||||
|
BfIRValue CreateSetRet(BfIRValue val, int returnTypeId);
|
||||||
void CreateRetVoid();
|
void CreateRetVoid();
|
||||||
void CreateUnreachable();
|
void CreateUnreachable();
|
||||||
void Call_AddAttribute(BfIRValue callInst, int argIdx, BfIRAttribute attr);
|
void Call_AddAttribute(BfIRValue callInst, int argIdx, BfIRAttribute attr);
|
||||||
|
@ -1315,6 +1327,9 @@ public:
|
||||||
BfIRMDNode type, bool isLocalToUnit, BfIRValue val, BfIRMDNode Decl = BfIRMDNode());
|
BfIRMDNode type, bool isLocalToUnit, BfIRValue val, BfIRMDNode Decl = BfIRMDNode());
|
||||||
BfIRMDNode DbgCreateLexicalBlock(BfIRMDNode scope, BfIRMDNode file, int line, int col);
|
BfIRMDNode DbgCreateLexicalBlock(BfIRMDNode scope, BfIRMDNode file, int line, int col);
|
||||||
void DbgCreateAnnotation(BfIRMDNode scope, const StringImpl& name, BfIRValue value);
|
void DbgCreateAnnotation(BfIRMDNode scope, const StringImpl& name, BfIRValue value);
|
||||||
|
|
||||||
|
BfIRState GetState();
|
||||||
|
void SetState(const BfIRState& state);
|
||||||
};
|
};
|
||||||
|
|
||||||
NS_BF_END
|
NS_BF_END
|
||||||
|
|
|
@ -3522,7 +3522,11 @@ void BfIRCodeGen::HandleNextCmd()
|
||||||
NULL, llvm::GlobalValue::NotThreadLocal);
|
NULL, llvm::GlobalValue::NotThreadLocal);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
func->addAttribute(argIdx, LLVMMapAttribute(attribute));
|
{
|
||||||
|
auto attr = LLVMMapAttribute(attribute);
|
||||||
|
if (attr != llvm::Attribute::None)
|
||||||
|
func->addAttribute(argIdx, attr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case BfIRCmd_Func_AddAttribute1:
|
case BfIRCmd_Func_AddAttribute1:
|
||||||
|
|
|
@ -13639,6 +13639,9 @@ void BfModule::DoAddLocalVariable(BfLocalVariable* localVar)
|
||||||
|
|
||||||
void BfModule::DoLocalVariableDebugInfo(BfLocalVariable* localVarDef, bool doAliasValue, BfIRValue declareBefore, BfIRInitType initType)
|
void BfModule::DoLocalVariableDebugInfo(BfLocalVariable* localVarDef, bool doAliasValue, BfIRValue declareBefore, BfIRInitType initType)
|
||||||
{
|
{
|
||||||
|
if (localVarDef->mResolvedType->IsVar())
|
||||||
|
return;
|
||||||
|
|
||||||
if ((mBfIRBuilder->DbgHasInfo()) &&
|
if ((mBfIRBuilder->DbgHasInfo()) &&
|
||||||
((mCurMethodInstance == NULL) || (!mCurMethodInstance->mIsUnspecialized)) &&
|
((mCurMethodInstance == NULL) || (!mCurMethodInstance->mIsUnspecialized)) &&
|
||||||
(mHasFullDebugInfo) &&
|
(mHasFullDebugInfo) &&
|
||||||
|
@ -14460,19 +14463,31 @@ void BfModule::CreateReturn(BfIRValue val)
|
||||||
mBfIRBuilder->CreateRet(val);
|
mBfIRBuilder->CreateRet(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BfModule::EmitReturn(BfIRValue val)
|
void BfModule::EmitReturn(const BfTypedValue& val)
|
||||||
{
|
{
|
||||||
if (mCurMethodState->mIRExitBlock)
|
if (mCurMethodState->mIRExitBlock)
|
||||||
{
|
{
|
||||||
if (!mCurMethodInstance->mReturnType->IsValuelessType())
|
if (!mCurMethodInstance->mReturnType->IsValuelessType())
|
||||||
{
|
{
|
||||||
if (val) // We allow for val to be empty if we know we've already written the value to mRetVal
|
if (val) // We allow for val to be empty if we know we've already written the value to mRetVal
|
||||||
|
{
|
||||||
|
if ((mCurMethodState->mRetValAddr) || (mCurMethodState->mRetVal))
|
||||||
{
|
{
|
||||||
BfIRValue retVal = mCurMethodState->mRetVal.mValue;
|
BfIRValue retVal = mCurMethodState->mRetVal.mValue;
|
||||||
if (!mCurMethodState->mRetVal)
|
if (!mCurMethodState->mRetVal)
|
||||||
retVal = mBfIRBuilder->CreateLoad(mCurMethodState->mRetValAddr);
|
retVal = mBfIRBuilder->CreateLoad(mCurMethodState->mRetValAddr);
|
||||||
|
|
||||||
mBfIRBuilder->CreateStore(val, retVal);
|
mBfIRBuilder->CreateStore(val.mValue, retVal);
|
||||||
|
}
|
||||||
|
else if (mIsConstModule)
|
||||||
|
{
|
||||||
|
mBfIRBuilder->CreateSetRet(val.mValue, val.mType->mTypeId);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Just ignore
|
||||||
|
BF_ASSERT(mCurMethodInstance->mReturnType->IsVar());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
EmitDeferredScopeCalls(true, NULL, mCurMethodState->mIRExitBlock);
|
EmitDeferredScopeCalls(true, NULL, mCurMethodState->mIRExitBlock);
|
||||||
|
@ -14486,7 +14501,7 @@ void BfModule::EmitReturn(BfIRValue val)
|
||||||
if (mCurMethodInstance->mReturnType->IsValuelessType())
|
if (mCurMethodInstance->mReturnType->IsValuelessType())
|
||||||
mBfIRBuilder->CreateRetVoid();
|
mBfIRBuilder->CreateRetVoid();
|
||||||
else
|
else
|
||||||
mBfIRBuilder->CreateRet(val);
|
mBfIRBuilder->CreateRet(val.mValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15609,6 +15624,8 @@ void BfModule::SetupIRMethod(BfMethodInstance* methodInstance, BfIRFunction func
|
||||||
if (methodInstance == NULL)
|
if (methodInstance == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (methodInstance->mReturnType->IsVar())
|
||||||
|
mBfIRBuilder->Func_AddAttribute(func, -1, BfIRAttribute_VarRet);
|
||||||
if (methodDef->mImportKind == BfImportKind_Export)
|
if (methodDef->mImportKind == BfImportKind_Export)
|
||||||
mBfIRBuilder->Func_AddAttribute(func, -1, BFIRAttribute_DllExport);
|
mBfIRBuilder->Func_AddAttribute(func, -1, BFIRAttribute_DllExport);
|
||||||
if (methodDef->mIsNoReturn)
|
if (methodDef->mIsNoReturn)
|
||||||
|
@ -19279,6 +19296,12 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup)
|
||||||
{
|
{
|
||||||
bool isEmptyBodied = BfNodeDynCast<BfTokenNode>(methodDef->mBody) != NULL;
|
bool isEmptyBodied = BfNodeDynCast<BfTokenNode>(methodDef->mBody) != NULL;
|
||||||
|
|
||||||
|
bool wantsRetVal = true;
|
||||||
|
if ((mIsConstModule) && (methodDef->mMethodType != BfMethodType_CtorCalcAppend))
|
||||||
|
wantsRetVal = false;
|
||||||
|
else if (mCurMethodInstance->mReturnType->IsVar())
|
||||||
|
wantsRetVal = false;
|
||||||
|
|
||||||
if ((!mCurMethodInstance->mReturnType->IsValuelessType()) && (!isEmptyBodied))
|
if ((!mCurMethodInstance->mReturnType->IsValuelessType()) && (!isEmptyBodied))
|
||||||
{
|
{
|
||||||
mBfIRBuilder->PopulateType(mCurMethodInstance->mReturnType);
|
mBfIRBuilder->PopulateType(mCurMethodInstance->mReturnType);
|
||||||
|
@ -19291,7 +19314,7 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup)
|
||||||
mBfIRBuilder->ClearDebugLocation(storeInst);
|
mBfIRBuilder->ClearDebugLocation(storeInst);
|
||||||
mCurMethodState->mRetValAddr = allocaInst;
|
mCurMethodState->mRetValAddr = allocaInst;
|
||||||
}
|
}
|
||||||
else
|
else if (wantsRetVal)
|
||||||
{
|
{
|
||||||
auto allocaInst = AllocLocalVariable(mCurMethodInstance->mReturnType, "__return", false);
|
auto allocaInst = AllocLocalVariable(mCurMethodInstance->mReturnType, "__return", false);
|
||||||
mCurMethodState->mRetVal = BfTypedValue(allocaInst, mCurMethodInstance->mReturnType, true);
|
mCurMethodState->mRetVal = BfTypedValue(allocaInst, mCurMethodInstance->mReturnType, true);
|
||||||
|
@ -19414,7 +19437,7 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup)
|
||||||
{
|
{
|
||||||
mCurMethodState->mHadReturn = true;
|
mCurMethodState->mHadReturn = true;
|
||||||
retVal = LoadOrAggregateValue(retVal);
|
retVal = LoadOrAggregateValue(retVal);
|
||||||
EmitReturn(retVal.mValue);
|
EmitReturn(retVal);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21211,14 +21234,13 @@ genericParam->mExternType = GetPrimitiveType(BfTypeCode_Var);
|
||||||
(methodDef->mReturnTypeRef != NULL))
|
(methodDef->mReturnTypeRef != NULL))
|
||||||
{
|
{
|
||||||
SetAndRestoreValue<bool> prevIngoreErrors(mIgnoreErrors, mIgnoreErrors || (methodDef->GetPropertyDeclaration() != NULL));
|
SetAndRestoreValue<bool> prevIngoreErrors(mIgnoreErrors, mIgnoreErrors || (methodDef->GetPropertyDeclaration() != NULL));
|
||||||
resolvedReturnType = ResolveTypeRef(methodDef->mReturnTypeRef, BfPopulateType_Declaration,
|
|
||||||
(BfResolveTypeRefFlags)(BfResolveTypeRefFlag_NoResolveGenericParam | BfResolveTypeRefFlag_AllowRef | BfResolveTypeRefFlag_AllowRefGeneric));
|
|
||||||
|
|
||||||
if ((resolvedReturnType != NULL) && (resolvedReturnType->IsVar()) && (methodDef->mMethodType != BfMethodType_Mixin))
|
BfResolveTypeRefFlags flags = (BfResolveTypeRefFlags)(BfResolveTypeRefFlag_NoResolveGenericParam | BfResolveTypeRefFlag_AllowRef | BfResolveTypeRefFlag_AllowRefGeneric);
|
||||||
{
|
|
||||||
Fail("Cannot declare var return types", methodDef->mReturnTypeRef);
|
if ((methodDef->mIsConstEval) && (methodDef->mReturnTypeRef->IsA<BfVarTypeReference>()))
|
||||||
resolvedReturnType = GetPrimitiveType(BfTypeCode_Var);
|
resolvedReturnType = GetPrimitiveType(BfTypeCode_Var);
|
||||||
}
|
else
|
||||||
|
resolvedReturnType = ResolveTypeRef(methodDef->mReturnTypeRef, BfPopulateType_Declaration, flags);
|
||||||
|
|
||||||
if (resolvedReturnType == NULL)
|
if (resolvedReturnType == NULL)
|
||||||
resolvedReturnType = GetPrimitiveType(BfTypeCode_Var);
|
resolvedReturnType = GetPrimitiveType(BfTypeCode_Var);
|
||||||
|
|
|
@ -1552,7 +1552,7 @@ public:
|
||||||
|
|
||||||
// Util
|
// Util
|
||||||
void CreateReturn(BfIRValue val);
|
void CreateReturn(BfIRValue val);
|
||||||
void EmitReturn(BfIRValue val);
|
void EmitReturn(const BfTypedValue& val);
|
||||||
void EmitDefaultReturn();
|
void EmitDefaultReturn();
|
||||||
void EmitDeferredCall(BfModuleMethodInstance moduleMethodInstance, SizedArrayImpl<BfIRValue>& llvmArgs, BfDeferredBlockFlags flags = BfDeferredBlockFlag_None);
|
void EmitDeferredCall(BfModuleMethodInstance moduleMethodInstance, SizedArrayImpl<BfIRValue>& llvmArgs, BfDeferredBlockFlags flags = BfDeferredBlockFlag_None);
|
||||||
bool AddDeferredCallEntry(BfDeferredCallEntry* deferredCallEntry, BfScopeData* scope);
|
bool AddDeferredCallEntry(BfDeferredCallEntry* deferredCallEntry, BfScopeData* scope);
|
||||||
|
|
|
@ -1148,7 +1148,7 @@ void BfMethodInstance::GetIRFunctionInfo(BfModule* module, BfIRType& returnType,
|
||||||
auto irReturnType = module->GetIRLoweredType(loweredReturnTypeCode, loweredReturnTypeCode2);
|
auto irReturnType = module->GetIRLoweredType(loweredReturnTypeCode, loweredReturnTypeCode2);
|
||||||
returnType = irReturnType;
|
returnType = irReturnType;
|
||||||
}
|
}
|
||||||
else if (mReturnType->IsValuelessType())
|
else if ((mReturnType->IsValuelessType()) || (mReturnType->IsVar()))
|
||||||
{
|
{
|
||||||
auto voidType = module->GetPrimitiveType(BfTypeCode_None);
|
auto voidType = module->GetPrimitiveType(BfTypeCode_None);
|
||||||
returnType = module->mBfIRBuilder->MapType(voidType);
|
returnType = module->mBfIRBuilder->MapType(voidType);
|
||||||
|
|
|
@ -3787,9 +3787,9 @@ void BfModule::Visit(BfThrowStatement* throwStmt)
|
||||||
Fail("Exceptions are not supported", throwStmt->mThrowToken);
|
Fail("Exceptions are not supported", throwStmt->mThrowToken);
|
||||||
|
|
||||||
if (mCurMethodInstance->mReturnType->IsVoid())
|
if (mCurMethodInstance->mReturnType->IsVoid())
|
||||||
EmitReturn(BfIRValue());
|
EmitReturn(BfTypedValue());
|
||||||
else
|
else
|
||||||
EmitReturn(GetDefaultValue(mCurMethodInstance->mReturnType));
|
EmitReturn(GetDefaultTypedValue(mCurMethodInstance->mReturnType));
|
||||||
}
|
}
|
||||||
|
|
||||||
void BfModule::Visit(BfDeleteStatement* deleteStmt)
|
void BfModule::Visit(BfDeleteStatement* deleteStmt)
|
||||||
|
@ -4927,7 +4927,7 @@ void BfModule::Visit(BfReturnStatement* returnStmt)
|
||||||
MarkScopeLeft(&mCurMethodState->mHeadScope);
|
MarkScopeLeft(&mCurMethodState->mHeadScope);
|
||||||
if (retType->IsVoid())
|
if (retType->IsVoid())
|
||||||
{
|
{
|
||||||
EmitReturn(BfIRValue());
|
EmitReturn(BfTypedValue());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4937,11 +4937,13 @@ void BfModule::Visit(BfReturnStatement* returnStmt)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
EmitReturn(GetDefaultValue(retType));
|
EmitReturn(GetDefaultTypedValue(retType));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
BfType* expectingReturnType = retType;
|
BfType* expectingReturnType = retType;
|
||||||
|
if ((expectingReturnType != NULL) && (expectingReturnType->IsVar()))
|
||||||
|
expectingReturnType = NULL;
|
||||||
|
|
||||||
BfType* origType;
|
BfType* origType;
|
||||||
BfExprEvaluator exprEvaluator(this);
|
BfExprEvaluator exprEvaluator(this);
|
||||||
|
@ -4964,21 +4966,21 @@ void BfModule::Visit(BfReturnStatement* returnStmt)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
EmitReturn(BfIRValue());
|
EmitReturn(BfTypedValue());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (retValue.mType->IsVar())
|
if (retValue.mType->IsVar())
|
||||||
{
|
{
|
||||||
EmitReturn(BfIRValue());
|
EmitReturn(BfTypedValue());
|
||||||
}
|
}
|
||||||
else if (retValue.mType->IsVoid())
|
else if (retValue.mType->IsVoid())
|
||||||
{
|
{
|
||||||
if (retType->IsVoid())
|
if (retType->IsVoid())
|
||||||
{
|
{
|
||||||
Warn(0, "Returning void value", returnStmt->mReturnToken);
|
Warn(0, "Returning void value", returnStmt->mReturnToken);
|
||||||
EmitReturn(BfIRValue());
|
EmitReturn(BfTypedValue());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -4987,7 +4989,7 @@ void BfModule::Visit(BfReturnStatement* returnStmt)
|
||||||
{
|
{
|
||||||
expectingReturnType = NULL;
|
expectingReturnType = NULL;
|
||||||
Fail("Attempting to return value from void method", returnStmt->mExpression);
|
Fail("Attempting to return value from void method", returnStmt->mExpression);
|
||||||
EmitReturn(BfIRValue());
|
EmitReturn(BfTypedValue());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4997,9 +4999,9 @@ void BfModule::Visit(BfReturnStatement* returnStmt)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!alreadyWritten)
|
if (!alreadyWritten)
|
||||||
EmitReturn(LoadOrAggregateValue(retValue).mValue);
|
EmitReturn(LoadOrAggregateValue(retValue));
|
||||||
else
|
else
|
||||||
EmitReturn(BfIRValue());
|
EmitReturn(BfTypedValue());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -83,6 +83,7 @@ static CeOpInfo gOpInfo[] =
|
||||||
{
|
{
|
||||||
{"InvalidOp"},
|
{"InvalidOp"},
|
||||||
{"Ret"},
|
{"Ret"},
|
||||||
|
{"SetRet", CEOI_None, CEOI_IMM32},
|
||||||
{"Jmp", CEOI_None, CEOI_JMPREL},
|
{"Jmp", CEOI_None, CEOI_JMPREL},
|
||||||
{"JmpIf", CEOI_None, CEOI_JMPREL, CEOI_FrameRef},
|
{"JmpIf", CEOI_None, CEOI_JMPREL, CEOI_FrameRef},
|
||||||
{"JmpIfNot", CEOI_None, CEOI_JMPREL, CEOI_FrameRef},
|
{"JmpIfNot", CEOI_None, CEOI_JMPREL, CEOI_FrameRef},
|
||||||
|
@ -1123,13 +1124,11 @@ void CeBuilder::HandleParams()
|
||||||
|
|
||||||
int frameOffset = 0;
|
int frameOffset = 0;
|
||||||
|
|
||||||
if (retType->mSize > 0)
|
if (mCeFunction->mMaxReturnSize > 0)
|
||||||
{
|
{
|
||||||
mReturnVal.mKind = CeOperandKind_AllocaAddr;
|
mReturnVal.mKind = CeOperandKind_AllocaAddr;
|
||||||
mReturnVal.mFrameOfs = frameOffset;
|
mReturnVal.mFrameOfs = frameOffset;
|
||||||
mReturnVal.mType = retType;
|
frameOffset += mCeFunction->mMaxReturnSize;
|
||||||
|
|
||||||
frameOffset += retType->mSize;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int paramOfs = 0;
|
int paramOfs = 0;
|
||||||
|
@ -1157,6 +1156,7 @@ void CeBuilder::HandleParams()
|
||||||
void CeBuilder::Build()
|
void CeBuilder::Build()
|
||||||
{
|
{
|
||||||
auto irCodeGen = mCeMachine->mCeModule->mBfIRBuilder->mBeIRCodeGen;
|
auto irCodeGen = mCeMachine->mCeModule->mBfIRBuilder->mBeIRCodeGen;
|
||||||
|
auto irBuilder = mCeMachine->mCeModule->mBfIRBuilder;
|
||||||
auto beModule = irCodeGen->mBeModule;
|
auto beModule = irCodeGen->mBeModule;
|
||||||
|
|
||||||
mCeFunction->mFailed = true;
|
mCeFunction->mFailed = true;
|
||||||
|
@ -1169,15 +1169,17 @@ void CeBuilder::Build()
|
||||||
|
|
||||||
BfMethodInstance dupMethodInstance;
|
BfMethodInstance dupMethodInstance;
|
||||||
dupMethodInstance.CopyFrom(methodInstance);
|
dupMethodInstance.CopyFrom(methodInstance);
|
||||||
//dupMethodInstance.mIRFunction = workItem.mFunc;
|
|
||||||
dupMethodInstance.mIsReified = true;
|
dupMethodInstance.mIsReified = true;
|
||||||
dupMethodInstance.mInCEMachine = false; // Only have the original one
|
dupMethodInstance.mInCEMachine = false; // Only have the original one
|
||||||
|
|
||||||
int startFunctionCount = (int)beModule->mFunctions.size();
|
int startFunctionCount = (int)beModule->mFunctions.size();
|
||||||
//int startGlobalVariableCount = (int)beModule->mGlobalVariables.size();
|
|
||||||
|
|
||||||
mCeMachine->mCeModule->mHadBuildError = false;
|
mCeMachine->mCeModule->mHadBuildError = false;
|
||||||
|
auto irState = irBuilder->GetState();
|
||||||
|
auto beState = irCodeGen->GetState();
|
||||||
mCeMachine->mCeModule->ProcessMethod(&dupMethodInstance, true);
|
mCeMachine->mCeModule->ProcessMethod(&dupMethodInstance, true);
|
||||||
|
irCodeGen->SetState(beState);
|
||||||
|
irBuilder->SetState(irState);
|
||||||
|
|
||||||
if (!dupMethodInstance.mIRFunction)
|
if (!dupMethodInstance.mIRFunction)
|
||||||
{
|
{
|
||||||
|
@ -1197,6 +1199,7 @@ void CeBuilder::Build()
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
CeFunction* innerFunction = new CeFunction();
|
CeFunction* innerFunction = new CeFunction();
|
||||||
|
innerFunction->mIsVarReturn = beFunction->mIsVarReturn;
|
||||||
innerFunction->mCeInnerFunctionInfo = new CeInnerFunctionInfo();
|
innerFunction->mCeInnerFunctionInfo = new CeInnerFunctionInfo();
|
||||||
innerFunction->mCeInnerFunctionInfo->mName = beFunction->mName;
|
innerFunction->mCeInnerFunctionInfo->mName = beFunction->mName;
|
||||||
innerFunction->mCeInnerFunctionInfo->mBeFunction = beFunction;
|
innerFunction->mCeInnerFunctionInfo->mBeFunction = beFunction;
|
||||||
|
@ -1294,6 +1297,17 @@ void CeBuilder::Build()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
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,6 +1802,7 @@ void CeBuilder::Build()
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case BeRetInst::TypeId:
|
case BeRetInst::TypeId:
|
||||||
|
case BeSetRetInst::TypeId:
|
||||||
{
|
{
|
||||||
auto castedInst = (BeRetInst*)inst;
|
auto castedInst = (BeRetInst*)inst;
|
||||||
if (castedInst->mRetValue != NULL)
|
if (castedInst->mRetValue != NULL)
|
||||||
|
@ -1797,7 +1812,15 @@ void CeBuilder::Build()
|
||||||
EmitSizedOp(CeOp_Move_8, mcVal, NULL, true);
|
EmitSizedOp(CeOp_Move_8, mcVal, NULL, true);
|
||||||
Emit((int32)mReturnVal.mFrameOfs);
|
Emit((int32)mReturnVal.mFrameOfs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (instType == BeRetInst::TypeId)
|
||||||
Emit(CeOp_Ret);
|
Emit(CeOp_Ret);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto setRetInst = (BeSetRetInst*)inst;
|
||||||
|
Emit(CeOp_SetRetType);
|
||||||
|
Emit((int32)setRetInst->mReturnTypeId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case BeCmpInst::TypeId:
|
case BeCmpInst::TypeId:
|
||||||
|
@ -3483,6 +3506,9 @@ BfIRValue CeMachine::CreateConstant(BfModule* module, uint8* ptr, BfType* bfType
|
||||||
{
|
{
|
||||||
auto typeInst = bfType->ToTypeInstance();
|
auto typeInst = bfType->ToTypeInstance();
|
||||||
|
|
||||||
|
if (typeInst->mIsUnion)
|
||||||
|
return BfIRValue();
|
||||||
|
|
||||||
uint8* instData = ptr;
|
uint8* instData = ptr;
|
||||||
// if ((typeInst->IsObject()) && (!isBaseType))
|
// if ((typeInst->IsObject()) && (!isBaseType))
|
||||||
// {
|
// {
|
||||||
|
@ -3744,11 +3770,12 @@ BfIRValue CeMachine::CreateConstant(BfModule* module, uint8* ptr, BfType* bfType
|
||||||
instPtr = &ceFunction->mCode[0]; \
|
instPtr = &ceFunction->mCode[0]; \
|
||||||
CE_CHECKSTACK();
|
CE_CHECKSTACK();
|
||||||
|
|
||||||
bool CeMachine::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* startFramePtr)
|
bool CeMachine::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* startFramePtr, BfType*& returnType)
|
||||||
{
|
{
|
||||||
mExecuteId++;
|
mExecuteId++;
|
||||||
|
|
||||||
CeFunction* ceFunction = startFunction;
|
CeFunction* ceFunction = startFunction;
|
||||||
|
returnType = startFunction->mMethodInstance->mReturnType;
|
||||||
uint8* memStart = &mMemory[0];
|
uint8* memStart = &mMemory[0];
|
||||||
int memSize = mMemory.mSize;
|
int memSize = mMemory.mSize;
|
||||||
uint8* instPtr = (ceFunction->mCode.IsEmpty()) ? NULL : &ceFunction->mCode[0];
|
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;
|
volatile bool* cancelPtr = &mCompiler->mCanceling;
|
||||||
|
|
||||||
|
|
||||||
auto _GetCurFrame = [&]()
|
auto _GetCurFrame = [&]()
|
||||||
{
|
{
|
||||||
CeFrame ceFrame;
|
CeFrame ceFrame;
|
||||||
ceFrame.mFunction = ceFunction;
|
ceFrame.mFunction = ceFunction;
|
||||||
|
ceFrame.mReturnType = returnType;
|
||||||
ceFrame.mFrameAddr = framePtr - memStart;
|
ceFrame.mFrameAddr = framePtr - memStart;
|
||||||
ceFrame.mStackAddr = stackPtr - memStart;
|
ceFrame.mStackAddr = stackPtr - memStart;
|
||||||
ceFrame.mInstPtr = instPtr;
|
ceFrame.mInstPtr = instPtr;
|
||||||
|
@ -4027,6 +4054,7 @@ bool CeMachine::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (!checkFunction->mFailed)
|
if (!checkFunction->mFailed)
|
||||||
return true;
|
return true;
|
||||||
auto error = Fail(_GetCurFrame(), "Method call failed");
|
auto error = Fail(_GetCurFrame(), "Method call failed");
|
||||||
|
@ -4070,10 +4098,18 @@ bool CeMachine::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
|
||||||
instPtr = ceFrame.mInstPtr;
|
instPtr = ceFrame.mInstPtr;
|
||||||
stackPtr = memStart + ceFrame.mStackAddr;
|
stackPtr = memStart + ceFrame.mStackAddr;
|
||||||
framePtr = memStart + ceFrame.mFrameAddr;
|
framePtr = memStart + ceFrame.mFrameAddr;
|
||||||
|
returnType = ceFrame.mReturnType;
|
||||||
|
|
||||||
mCallStack.pop_back();
|
mCallStack.pop_back();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case CeOp_SetRetType:
|
||||||
|
{
|
||||||
|
int typeId = CE_GETINST(int32);
|
||||||
|
returnType = GetBfType(typeId);
|
||||||
|
BF_ASSERT(returnType != NULL);
|
||||||
|
}
|
||||||
|
break;
|
||||||
case CeOp_Jmp:
|
case CeOp_Jmp:
|
||||||
{
|
{
|
||||||
auto relOfs = CE_GETINST(int32);
|
auto relOfs = CE_GETINST(int32);
|
||||||
|
@ -4666,6 +4702,8 @@ bool CeMachine::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
|
||||||
bool handled = false;
|
bool handled = false;
|
||||||
if (!_CheckFunction(callFunction, handled))
|
if (!_CheckFunction(callFunction, handled))
|
||||||
return false;
|
return false;
|
||||||
|
if (callFunction->mIsVarReturn)
|
||||||
|
_Fail("Illegal call to method with 'var' return.");
|
||||||
if (handled)
|
if (handled)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -5284,6 +5322,7 @@ void CeMachine::PrepareFunction(CeFunction* ceFunction, CeBuilder* parentBuilder
|
||||||
|
|
||||||
BF_ASSERT(!ceFunction->mInitialized);
|
BF_ASSERT(!ceFunction->mInitialized);
|
||||||
ceFunction->mInitialized = true;
|
ceFunction->mInitialized = true;
|
||||||
|
ceFunction->mGenerating = true;
|
||||||
|
|
||||||
CeBuilder ceBuilder;
|
CeBuilder ceBuilder;
|
||||||
ceBuilder.mParentBuilder = parentBuilder;
|
ceBuilder.mParentBuilder = parentBuilder;
|
||||||
|
@ -5292,6 +5331,8 @@ void CeMachine::PrepareFunction(CeFunction* ceFunction, CeBuilder* parentBuilder
|
||||||
ceBuilder.mCeFunction = ceFunction;
|
ceBuilder.mCeFunction = ceFunction;
|
||||||
ceBuilder.Build();
|
ceBuilder.Build();
|
||||||
|
|
||||||
|
ceFunction->mGenerating = false;
|
||||||
|
|
||||||
/*if (!ceFunction->mCode.IsEmpty())
|
/*if (!ceFunction->mCode.IsEmpty())
|
||||||
{
|
{
|
||||||
CeDumpContext dumpCtx;
|
CeDumpContext dumpCtx;
|
||||||
|
@ -5375,6 +5416,7 @@ CeFunction* CeMachine::GetFunction(BfMethodInstance* methodInstance, BfIRValue f
|
||||||
BF_ASSERT(ceFunctionInfo->mCeFunction == NULL);
|
BF_ASSERT(ceFunctionInfo->mCeFunction == NULL);
|
||||||
|
|
||||||
ceFunction = new CeFunction();
|
ceFunction = new CeFunction();
|
||||||
|
ceFunction->mIsVarReturn = methodInstance->mReturnType->IsVar();
|
||||||
ceFunction->mCeFunctionInfo = ceFunctionInfo;
|
ceFunction->mCeFunctionInfo = ceFunctionInfo;
|
||||||
ceFunction->mMethodInstance = methodInstance;
|
ceFunction->mMethodInstance = methodInstance;
|
||||||
|
|
||||||
|
@ -5505,6 +5547,13 @@ BfTypedValue CeMachine::Call(BfAstNode* targetSrc, BfModule* module, BfMethodIns
|
||||||
|
|
||||||
bool added = false;
|
bool added = false;
|
||||||
CeFunction* ceFunction = GetFunction(methodInstance, BfIRValue(), added);
|
CeFunction* ceFunction = GetFunction(methodInstance, BfIRValue(), added);
|
||||||
|
|
||||||
|
if (ceFunction->mGenerating)
|
||||||
|
{
|
||||||
|
Fail("Recursive var-inference");
|
||||||
|
return BfTypedValue();
|
||||||
|
}
|
||||||
|
|
||||||
if (!ceFunction->mInitialized)
|
if (!ceFunction->mInitialized)
|
||||||
PrepareFunction(ceFunction, NULL);
|
PrepareFunction(ceFunction, NULL);
|
||||||
|
|
||||||
|
@ -5631,15 +5680,15 @@ BfTypedValue CeMachine::Call(BfAstNode* targetSrc, BfModule* module, BfMethodIns
|
||||||
}
|
}
|
||||||
|
|
||||||
addr_ce retAddr = 0;
|
addr_ce retAddr = 0;
|
||||||
auto returnType = methodInstance->mReturnType;
|
if (ceFunction->mMaxReturnSize > 0)
|
||||||
if (!returnType->IsValuelessType())
|
|
||||||
{
|
{
|
||||||
int retSize = methodInstance->mReturnType->mSize;
|
int retSize = ceFunction->mMaxReturnSize;
|
||||||
stackPtr -= retSize;
|
stackPtr -= retSize;
|
||||||
retAddr = stackPtr - memStart;
|
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];
|
memStart = &mMemory[0];
|
||||||
|
|
||||||
addr_ce retInstAddr = retAddr;
|
addr_ce retInstAddr = retAddr;
|
||||||
|
|
|
@ -65,6 +65,7 @@ enum CeOp : int16
|
||||||
{
|
{
|
||||||
CeOp_InvalidOp,
|
CeOp_InvalidOp,
|
||||||
CeOp_Ret,
|
CeOp_Ret,
|
||||||
|
CeOp_SetRetType,
|
||||||
CeOp_Jmp,
|
CeOp_Jmp,
|
||||||
CeOp_JmpIf,
|
CeOp_JmpIf,
|
||||||
CeOp_JmpIfNot,
|
CeOp_JmpIfNot,
|
||||||
|
@ -331,8 +332,10 @@ public:
|
||||||
CeInnerFunctionInfo* mCeInnerFunctionInfo;
|
CeInnerFunctionInfo* mCeInnerFunctionInfo;
|
||||||
BfMethodInstance* mMethodInstance;
|
BfMethodInstance* mMethodInstance;
|
||||||
CeFunctionKind mFunctionKind;
|
CeFunctionKind mFunctionKind;
|
||||||
|
bool mGenerating;
|
||||||
bool mInitialized;
|
bool mInitialized;
|
||||||
bool mFailed;
|
bool mFailed;
|
||||||
|
bool mIsVarReturn;
|
||||||
Array<uint8> mCode;
|
Array<uint8> mCode;
|
||||||
Array<String> mFiles;
|
Array<String> mFiles;
|
||||||
Array<CeEmitEntry> mEmitTable;
|
Array<CeEmitEntry> mEmitTable;
|
||||||
|
@ -344,6 +347,7 @@ public:
|
||||||
Array<CeFunction*> mInnerFunctions;
|
Array<CeFunction*> mInnerFunctions;
|
||||||
String mGenError;
|
String mGenError;
|
||||||
int mFrameSize;
|
int mFrameSize;
|
||||||
|
int mMaxReturnSize;
|
||||||
int mId;
|
int mId;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -352,10 +356,13 @@ public:
|
||||||
mCeFunctionInfo = NULL;
|
mCeFunctionInfo = NULL;
|
||||||
mCeInnerFunctionInfo = NULL;
|
mCeInnerFunctionInfo = NULL;
|
||||||
mFunctionKind = CeFunctionKind_Normal;
|
mFunctionKind = CeFunctionKind_Normal;
|
||||||
|
mGenerating = false;
|
||||||
mInitialized = false;
|
mInitialized = false;
|
||||||
mMethodInstance = NULL;
|
mMethodInstance = NULL;
|
||||||
mFailed = false;
|
mFailed = false;
|
||||||
|
mIsVarReturn = false;
|
||||||
mFrameSize = 0;
|
mFrameSize = 0;
|
||||||
|
mMaxReturnSize = 0;
|
||||||
mId = -1;
|
mId = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -559,6 +566,7 @@ public:
|
||||||
addr_ce mStackAddr;
|
addr_ce mStackAddr;
|
||||||
addr_ce mFrameAddr;
|
addr_ce mFrameAddr;
|
||||||
uint8* mInstPtr;
|
uint8* mInstPtr;
|
||||||
|
BfType* mReturnType;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CeFrame()
|
CeFrame()
|
||||||
|
@ -567,6 +575,7 @@ public:
|
||||||
mStackAddr = 0;
|
mStackAddr = 0;
|
||||||
mFrameAddr = 0;
|
mFrameAddr = 0;
|
||||||
mInstPtr = NULL;
|
mInstPtr = NULL;
|
||||||
|
mReturnType = NULL;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -648,7 +657,7 @@ public:
|
||||||
CeErrorKind WriteConstant(CeConstStructData& data, BeConstant* constVal);
|
CeErrorKind WriteConstant(CeConstStructData& data, BeConstant* constVal);
|
||||||
BfIRValue CreateConstant(BfModule* module, uint8* ptr, BfType* type, BfType** outType = NULL);
|
BfIRValue CreateConstant(BfModule* module, uint8* ptr, BfType* type, BfType** outType = NULL);
|
||||||
void CreateFunction(BfMethodInstance* methodInstance, CeFunction* ceFunction);
|
void CreateFunction(BfMethodInstance* methodInstance, CeFunction* ceFunction);
|
||||||
bool Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* startFramePtr);
|
bool Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* startFramePtr, BfType*& returnType);
|
||||||
|
|
||||||
void PrepareFunction(CeFunction* methodInstance, CeBuilder* parentBuilder);
|
void PrepareFunction(CeFunction* methodInstance, CeBuilder* parentBuilder);
|
||||||
void MapFunctionId(CeFunction* ceFunction);
|
void MapFunctionId(CeFunction* ceFunction);
|
||||||
|
|
|
@ -121,9 +121,26 @@ namespace Tests
|
||||||
return sa.mA + sa.mB + tup.0 + tup.1 + arr[0] + arr[1];
|
return sa.mA + sa.mB + tup.0 + tup.1 + arr[0] + arr[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[ConstEval]
|
||||||
|
static var StrToValue(String str)
|
||||||
|
{
|
||||||
|
if (str.Contains('.'))
|
||||||
|
return float.Parse(str).Value;
|
||||||
|
return int.Parse(str).Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
class ClassA
|
||||||
|
{
|
||||||
|
public const let cVal0 = StrToValue("123");
|
||||||
|
public const let cVal1 = StrToValue("1.23");
|
||||||
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public static void TestBasics()
|
public static void TestBasics()
|
||||||
{
|
{
|
||||||
|
Test.Assert(ClassA.cVal0 == 123);
|
||||||
|
Test.Assert(ClassA.cVal0 == 1.23);
|
||||||
|
|
||||||
const int fac = Factorial(8);
|
const int fac = Factorial(8);
|
||||||
Test.Assert(fac == 40320);
|
Test.Assert(fac == 40320);
|
||||||
const int fib = Fibonacci(27);
|
const int fib = Fibonacci(27);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue