1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-08 11:38:21 +02:00

Added @return support

This commit is contained in:
Brian Fiete 2021-01-16 12:35:51 -08:00
parent f8ec709750
commit e06949dac1
10 changed files with 88 additions and 32 deletions

View file

@ -49,7 +49,7 @@ namespace System.Reflection
get get
{ {
if (Compiler.IsComptime) if (Compiler.IsComptime)
Type.[Friend]GetType((.)Type.[Friend]Comptime_Method_GetInfo(mNativeMethodInstance).mReturnTypeId); return Type.[Friend]GetType((.)Type.[Friend]Comptime_Method_GetInfo(mNativeMethodInstance).mReturnTypeId);
return null; return null;
} }
} }

View file

@ -583,7 +583,7 @@ namespace System
{ {
if (Compiler.IsComptime) if (Compiler.IsComptime)
{ {
return Comptime_Type_GetCustomAttribute((int32)TypeId, typeof(T).TypeId, null); return Comptime_Type_GetCustomAttribute((int32)TypeId, (.)typeof(T).TypeId, null);
} }
if (var typeInstance = this as TypeInstance) if (var typeInstance = this as TypeInstance)
@ -596,7 +596,7 @@ namespace System
if (Compiler.IsComptime) if (Compiler.IsComptime)
{ {
T val = ?; T val = ?;
if (Comptime_Type_GetCustomAttribute((int32)TypeId, typeof(T).TypeId, &val)) if (Comptime_Type_GetCustomAttribute((int32)TypeId, (.)typeof(T).TypeId, &val))
return val; return val;
return .Err; return .Err;
} }

View file

@ -426,6 +426,7 @@ BfCompiler::BfCompiler(BfSystem* bfSystem, bool isResolveOnly)
mOrderedAttributeTypeDef = NULL; mOrderedAttributeTypeDef = NULL;
mPointerTTypeDef = NULL; mPointerTTypeDef = NULL;
mPointerTypeDef = NULL; mPointerTypeDef = NULL;
mReflectTypeIdTypeDef = NULL;
mReflectArrayType = NULL; mReflectArrayType = NULL;
mReflectFieldDataDef = NULL; mReflectFieldDataDef = NULL;
mReflectFieldSplatDataDef = NULL; mReflectFieldSplatDataDef = NULL;
@ -6650,6 +6651,7 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory)
mOrderedAttributeTypeDef = _GetRequiredType("System.OrderedAttribute"); mOrderedAttributeTypeDef = _GetRequiredType("System.OrderedAttribute");
mPointerTTypeDef = _GetRequiredType("System.Pointer", 1); mPointerTTypeDef = _GetRequiredType("System.Pointer", 1);
mPointerTypeDef = _GetRequiredType("System.Pointer", 0); mPointerTypeDef = _GetRequiredType("System.Pointer", 0);
mReflectTypeIdTypeDef = _GetRequiredType("System.Reflection.TypeId");
mReflectArrayType = _GetRequiredType("System.Reflection.ArrayType"); mReflectArrayType = _GetRequiredType("System.Reflection.ArrayType");
mReflectFieldDataDef = _GetRequiredType("System.Reflection.TypeInstance.FieldData"); mReflectFieldDataDef = _GetRequiredType("System.Reflection.TypeInstance.FieldData");
mReflectFieldSplatDataDef = _GetRequiredType("System.Reflection.TypeInstance.FieldSplatData"); mReflectFieldSplatDataDef = _GetRequiredType("System.Reflection.TypeInstance.FieldSplatData");

View file

@ -374,9 +374,10 @@ public:
BfTypeDef* mMethodRefTypeDef; BfTypeDef* mMethodRefTypeDef;
BfTypeDef* mNullableTypeDef; BfTypeDef* mNullableTypeDef;
BfTypeDef* mPointerTTypeDef; BfTypeDef* mPointerTTypeDef;
BfTypeDef* mPointerTypeDef; BfTypeDef* mPointerTypeDef;
BfTypeDef* mReflectTypeIdTypeDef;
BfTypeDef* mReflectArrayType; BfTypeDef* mReflectArrayType;
BfTypeDef* mReflectFieldDataDef; BfTypeDef* mReflectFieldDataDef;
BfTypeDef* mReflectFieldSplatDataDef; BfTypeDef* mReflectFieldSplatDataDef;
@ -388,7 +389,7 @@ public:
BfTypeDef* mReflectSizedArrayType; BfTypeDef* mReflectSizedArrayType;
BfTypeDef* mReflectSpecializedGenericType; BfTypeDef* mReflectSpecializedGenericType;
BfTypeDef* mReflectTypeInstanceTypeDef; BfTypeDef* mReflectTypeInstanceTypeDef;
BfTypeDef* mReflectUnspecializedGenericType; BfTypeDef* mReflectUnspecializedGenericType;
BfTypeDef* mSizedArrayTypeDef; BfTypeDef* mSizedArrayTypeDef;
BfTypeDef* mAttributeTypeDef; BfTypeDef* mAttributeTypeDef;

View file

@ -3727,7 +3727,8 @@ BfTypedValue BfExprEvaluator::LookupIdentifier(BfAstNode* refNode, const StringI
wantName = findName; wantName = findName;
while (wantName.StartsWith("@")) while (wantName.StartsWith("@"))
{ {
varSkipCount++; if (wantName != "@return")
varSkipCount++;
wantName.Remove(0); wantName.Remove(0);
} }
} }
@ -9942,7 +9943,10 @@ bool BfExprEvaluator::LookupTypeProp(BfTypeOfExpression* typeOfExpr, BfIdentifie
else if (memberName == "IsSizedArray") else if (memberName == "IsSizedArray")
_BoolResult(type->IsSizedArray()); _BoolResult(type->IsSizedArray());
else if (memberName == "TypeId") else if (memberName == "TypeId")
{
_Int32Result(type->mTypeId); _Int32Result(type->mTypeId);
mResult.mType = mModule->ResolveTypeDef(mModule->mCompiler->mReflectTypeIdTypeDef);
}
else if (memberName == "GenericParamCount") else if (memberName == "GenericParamCount")
{ {
auto genericTypeInst = type->ToGenericTypeInstance(); auto genericTypeInst = type->ToGenericTypeInstance();

View file

@ -2236,6 +2236,28 @@ void BfModule::LocalVariableDone(BfLocalVariable* localVar, bool isMethodExit)
} }
} }
void BfModule::CreateRetValLocal()
{
if (mCurMethodState->mRetVal)
{
BfLocalVariable* localDef = new BfLocalVariable();
localDef->mName = "return";
localDef->mResolvedType = mCurMethodState->mRetVal.mType;
localDef->mAddr = mCurMethodState->mRetVal.mValue;
localDef->mAssignedKind = BfLocalVarAssignKind_Unconditional;
AddLocalVariableDef(localDef);
}
else if (mCurMethodState->mRetValAddr)
{
BfLocalVariable* localDef = new BfLocalVariable();
localDef->mName = "return";
localDef->mResolvedType = CreateRefType(mCurMethodInstance->mReturnType);
localDef->mAddr = mCurMethodState->mRetValAddr;
localDef->mAssignedKind = BfLocalVarAssignKind_Unconditional;
AddLocalVariableDef(localDef);
}
}
void BfModule::MarkDynStack(BfScopeData* scopeData) void BfModule::MarkDynStack(BfScopeData* scopeData)
{ {
auto checkScope = mCurMethodState->mCurScope; auto checkScope = mCurMethodState->mCurScope;
@ -5316,8 +5338,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
else else
typeDataVar = mBfIRBuilder->CreateConstNull(mBfIRBuilder->MapType(mContext->mBfTypeType)); typeDataVar = mBfIRBuilder->CreateConstNull(mBfIRBuilder->MapType(mContext->mBfTypeType));
mTypeDataRefs[typeInstance] = typeDataVar; mTypeDataRefs[type] = typeDataVar;
return typeDataVar; return typeDataVar;
} }
@ -6876,7 +6897,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
} }
typeDataVar = mBfIRBuilder->CreateBitCast(typeDataVar, mBfIRBuilder->MapType(mContext->mBfTypeType)); typeDataVar = mBfIRBuilder->CreateBitCast(typeDataVar, mBfIRBuilder->MapType(mContext->mBfTypeType));
mTypeDataRefs[typeInstance] = typeDataVar; mTypeDataRefs[typeInstance] = typeDataVar;
if ((!mIsComptimeModule) && (classVDataVar)) if ((!mIsComptimeModule) && (classVDataVar))
{ {
@ -13972,7 +13993,7 @@ void BfModule::CreateDIRetVal()
} }
mCurMethodState->mDIRetVal = mBfIRBuilder->DbgCreateAutoVariable(mCurMethodState->mCurScope->mDIScope, mCurMethodState->mDIRetVal = mBfIRBuilder->DbgCreateAutoVariable(mCurMethodState->mCurScope->mDIScope,
"__return", mCurFilePosition.mFileInstance->mDIFile, mCurFilePosition.mCurLine, mBfIRBuilder->DbgGetType(dbgType)); "@return", mCurFilePosition.mFileInstance->mDIFile, mCurFilePosition.mCurLine, mBfIRBuilder->DbgGetType(dbgType));
auto declareCall = mBfIRBuilder->DbgInsertDeclare(dbgValue, mCurMethodState->mDIRetVal); auto declareCall = mBfIRBuilder->DbgInsertDeclare(dbgValue, mCurMethodState->mDIRetVal);
} }
} }
@ -14292,6 +14313,9 @@ void BfModule::EmitDeferredScopeCalls(bool useSrcPositions, BfScopeData* scopeDa
{ {
if (deferredCallEntry->mDeferredBlock != NULL) if (deferredCallEntry->mDeferredBlock != NULL)
{ {
if (checkScope == &mCurMethodState->mHeadScope)
CreateRetValLocal();
SetAndRestoreValue<BfAstNode*> prevCustomAttribute(mCurMethodState->mEmitRefNode, deferredCallEntry->mEmitRefNode); SetAndRestoreValue<BfAstNode*> prevCustomAttribute(mCurMethodState->mEmitRefNode, deferredCallEntry->mEmitRefNode);
VisitEmbeddedStatement(deferredCallEntry->mDeferredBlock, NULL, BfEmbeddedStatementFlags_IsDeferredBlock); VisitEmbeddedStatement(deferredCallEntry->mDeferredBlock, NULL, BfEmbeddedStatementFlags_IsDeferredBlock);
} }
@ -14374,12 +14398,15 @@ void BfModule::EmitDeferredScopeCalls(bool useSrcPositions, BfScopeData* scopeDa
if (hasWork) if (hasWork)
{ {
SetAndRestoreValue<BfScopeData*> prevScope(mCurMethodState->mCurScope, checkScope); SetAndRestoreValue<BfScopeData*> prevScope(mCurMethodState->mCurScope, checkScope);
if (deferCloseNode != NULL) if (deferCloseNode != NULL)
{ {
UpdateSrcPos(deferCloseNode); UpdateSrcPos(deferCloseNode);
} }
if (checkScope == &mCurMethodState->mHeadScope)
CreateRetValLocal();
if (doneBlock) if (doneBlock)
{ {
bool crossingMixin = mCurMethodState->mCurScope->mMixinDepth != checkScope->mMixinDepth; bool crossingMixin = mCurMethodState->mCurScope->mMixinDepth != checkScope->mMixinDepth;

View file

@ -1776,6 +1776,7 @@ public:
BfLocalVariable* AddLocalVariableDef(BfLocalVariable* localVarDef, bool addDebugInfo = false, bool doAliasValue = false, BfIRValue declareBefore = BfIRValue(), BfIRInitType initType = BfIRInitType_NotSet); BfLocalVariable* AddLocalVariableDef(BfLocalVariable* localVarDef, bool addDebugInfo = false, bool doAliasValue = false, BfIRValue declareBefore = BfIRValue(), BfIRInitType initType = BfIRInitType_NotSet);
bool TryLocalVariableInit(BfLocalVariable* localVar); bool TryLocalVariableInit(BfLocalVariable* localVar);
void LocalVariableDone(BfLocalVariable* localVar, bool isMethodExit); void LocalVariableDone(BfLocalVariable* localVar, bool isMethodExit);
void CreateRetValLocal();
void CreateDIRetVal(); void CreateDIRetVal();
BfTypedValue CreateTuple(const Array<BfTypedValue>& values, const Array<String>& fieldNames); BfTypedValue CreateTuple(const Array<BfTypedValue>& values, const Array<String>& fieldNames);
void CheckTupleVariableDeclaration(BfTupleExpression* tupleExpr, BfType* initType); void CheckTupleVariableDeclaration(BfTupleExpression* tupleExpr, BfType* initType);

View file

@ -9768,11 +9768,12 @@ void BfReducer::HandleBlock(BfBlock* block, bool allowEndingExpression)
flags = (CreateStmtFlags)(flags | CreateStmtFlags_AllowUnterminatedExpression); flags = (CreateStmtFlags)(flags | CreateStmtFlags_AllowUnterminatedExpression);
auto statement = CreateStatement(node, flags); auto statement = CreateStatement(node, flags);
if (statement == NULL) if ((statement == NULL) && (mSource != NULL))
statement = mSource->CreateErrorNode(node); statement = mSource->CreateErrorNode(node);
isDone = !mVisitorPos.MoveNext(); isDone = !mVisitorPos.MoveNext();
mVisitorPos.Write(statement); if (statement != NULL)
mVisitorPos.Write(statement);
} }
mVisitorPos.Trim(); mVisitorPos.Trim();

View file

@ -2861,11 +2861,11 @@ addr_ce CeContext::GetReflectType(int typeId)
ceModule->PopulateType(bfType, BfPopulateType_DataAndMethods); ceModule->PopulateType(bfType, BfPopulateType_DataAndMethods);
Dictionary<int, int> usedStringMap; Dictionary<int, int> usedStringMap;
auto irData = ceModule->CreateTypeData(bfType, usedStringMap, true, true, true, false); auto irData = ceModule->CreateTypeData(bfType, usedStringMap, true, true, true, false);
BeValue* beValue = NULL; BeValue* beValue = NULL;
if (auto constant = mCeMachine->mCeModule->mBfIRBuilder->GetConstant(irData)) if (auto constant = mCeMachine->mCeModule->mBfIRBuilder->GetConstant(irData))
{ {
if (constant->mConstType == BfConstType_BitCast) if (constant->mConstType == BfConstType_BitCast)
{ {
auto bitcast = (BfConstantBitCast*)constant; auto bitcast = (BfConstantBitCast*)constant;
@ -2875,12 +2875,13 @@ addr_ce CeContext::GetReflectType(int typeId)
{ {
auto globalVar = (BfGlobalVar*)constant; auto globalVar = (BfGlobalVar*)constant;
beValue = mCeMachine->mCeModule->mBfIRBuilder->mBeIRCodeGen->GetBeValue(globalVar->mStreamId); beValue = mCeMachine->mCeModule->mBfIRBuilder->mBeIRCodeGen->GetBeValue(globalVar->mStreamId);
} }
} }
if (auto constant = BeValueDynCast<BeConstant>(beValue)) if (auto constant = BeValueDynCast<BeConstant>(beValue))
*addrPtr = GetConstantData(constant); *addrPtr = GetConstantData(constant);
// We need to 'get' again because we might have resized
return *addrPtr; return *addrPtr;
} }
@ -4103,9 +4104,8 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
{ {
int32 size = *(int32*)((uint8*)stackPtr + 4); int32 size = *(int32*)((uint8*)stackPtr + 4);
CE_CHECKALLOC(size); CE_CHECKALLOC(size);
uint8* ptr = CeMalloc(size); uint8* ptr = CeMalloc(size);
addr_ce& result = *(addr_ce*)((uint8*)stackPtr + 0); CeSetAddrVal(stackPtr + 0, ptr - memStart, ptrSize);
result = (addr_ce)(ptr - memStart);
handled = true; handled = true;
return true; return true;
} }
@ -4185,7 +4185,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
auto reflectType = GetReflectType(typeId); auto reflectType = GetReflectType(typeId);
_FixVariables(); _FixVariables();
*(addr_ce*)(stackPtr + 0) = reflectType; CeSetAddrVal(stackPtr + 0, reflectType, ptrSize);
handled = true; handled = true;
return true; return true;
} }
@ -4194,7 +4194,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
int32 typeId = *(int32*)((uint8*)stackPtr + ceModule->mSystem->mPtrSize); int32 typeId = *(int32*)((uint8*)stackPtr + ceModule->mSystem->mPtrSize);
auto reflectType = GetReflectType(typeId); auto reflectType = GetReflectType(typeId);
_FixVariables(); _FixVariables();
*(addr_ce*)(stackPtr + 0) = reflectType; CeSetAddrVal(stackPtr + 0, reflectType, ptrSize);
handled = true; handled = true;
return true; return true;
} }
@ -4209,7 +4209,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
} }
auto reflectType = GetReflectType(typeName); auto reflectType = GetReflectType(typeName);
_FixVariables(); _FixVariables();
*(addr_ce*)(stackPtr + 0) = reflectType; CeSetAddrVal(stackPtr + 0, reflectType, ptrSize);
handled = true; handled = true;
return true; return true;
} }
@ -4220,7 +4220,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
auto reflectType = GetReflectSpecializedType(typeAddr, typeSpan); auto reflectType = GetReflectSpecializedType(typeAddr, typeSpan);
_FixVariables(); _FixVariables();
*(addr_ce*)(stackPtr + 0) = reflectType; CeSetAddrVal(stackPtr + 0, reflectType, ptrSize);
handled = true; handled = true;
return true; return true;
} }
@ -4348,10 +4348,11 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
return false; return false;
} }
addr_ce stringAddr = GetString(methodInstance->GetParamName(paramIdx));
_FixVariables();
*(int32*)(stackPtr + 0) = methodInstance->GetParamType(paramIdx)->mTypeId; *(int32*)(stackPtr + 0) = methodInstance->GetParamType(paramIdx)->mTypeId;
*(int16*)(stackPtr + 4) = 0; // Flags *(int16*)(stackPtr + 4) = 0; // Flags
CeSetAddrVal(stackPtr + 4+2, GetString(methodInstance->GetParamName(paramIdx)), ptrSize); CeSetAddrVal(stackPtr + 4+2, stringAddr, ptrSize);
_FixVariables();
handled = true; handled = true;
return true; return true;
} }

View file

@ -48,8 +48,20 @@ namespace Tests
String emit = scope $"LogAttribute.gLog.AppendF($\"Called {method}"; String emit = scope $"LogAttribute.gLog.AppendF($\"Called {method}";
for (var fieldIdx < method.ParamCount) for (var fieldIdx < method.ParamCount)
emit.AppendF($" {{ {method.GetParamName(fieldIdx)} }}"); emit.AppendF($" {{ {method.GetParamName(fieldIdx)} }}");
emit.Append("\");"); emit.Append("\\n\");");
Compiler.EmitMethodEntry(method, emit); Compiler.EmitMethodEntry(method, emit);
if (var genericType = method.ReturnType as SpecializedGenericType)
{
if ((genericType.UnspecializedType == typeof(Result<>)) || (genericType.UnspecializedType == typeof(Result<,>)))
{
Compiler.EmitMethodExit(method, """
if (@return case .Err)
LogAttribute.gLog.AppendF($"Error: {@return}");
""");
}
}
} }
} }
@ -68,10 +80,16 @@ namespace Tests
} }
} }
[Log] enum MethodAErr
public static void MethodA(int a, int b)
{ {
ErrorA,
ErrorB
}
[Log]
static Result<int, MethodAErr> MethodA(int a, int b)
{
return .Err(.ErrorB);
} }
static Type GetBiggerType(Type t) static Type GetBiggerType(Type t)
@ -104,8 +122,9 @@ namespace Tests
Compiler.Mixin("int val = 99;"); Compiler.Mixin("int val = 99;");
Test.Assert(val == 99); Test.Assert(val == 99);
MethodA(34, 45);
Debug.Assert(LogAttribute.gLog == "Called Tests.Comptime.MethodA(int a, int b) 34 45"); MethodA(34, 45).IgnoreError();
Debug.Assert(LogAttribute.gLog == "Called Tests.Comptime.MethodA(int a, int b) 34 45\nError: Err(ErrorB)");
var v0 = GetBigger((int8)123); var v0 = GetBigger((int8)123);
Test.Assert(v0.GetType() == typeof(int16)); Test.Assert(v0.GetType() == typeof(int16));