diff --git a/BeefLibs/corlib/src/Reflection/CEMethodInfo.bf b/BeefLibs/corlib/src/Reflection/CEMethodInfo.bf index bc68d801..cc13dad1 100644 --- a/BeefLibs/corlib/src/Reflection/CEMethodInfo.bf +++ b/BeefLibs/corlib/src/Reflection/CEMethodInfo.bf @@ -49,7 +49,7 @@ namespace System.Reflection get { 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; } } diff --git a/BeefLibs/corlib/src/Type.bf b/BeefLibs/corlib/src/Type.bf index 99855f97..73d6acf1 100644 --- a/BeefLibs/corlib/src/Type.bf +++ b/BeefLibs/corlib/src/Type.bf @@ -583,7 +583,7 @@ namespace System { 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) @@ -596,7 +596,7 @@ namespace System if (Compiler.IsComptime) { 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 .Err; } diff --git a/IDEHelper/Compiler/BfCompiler.cpp b/IDEHelper/Compiler/BfCompiler.cpp index 573e6be9..16f103af 100644 --- a/IDEHelper/Compiler/BfCompiler.cpp +++ b/IDEHelper/Compiler/BfCompiler.cpp @@ -426,6 +426,7 @@ BfCompiler::BfCompiler(BfSystem* bfSystem, bool isResolveOnly) mOrderedAttributeTypeDef = NULL; mPointerTTypeDef = NULL; mPointerTypeDef = NULL; + mReflectTypeIdTypeDef = NULL; mReflectArrayType = NULL; mReflectFieldDataDef = NULL; mReflectFieldSplatDataDef = NULL; @@ -6650,6 +6651,7 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory) mOrderedAttributeTypeDef = _GetRequiredType("System.OrderedAttribute"); mPointerTTypeDef = _GetRequiredType("System.Pointer", 1); mPointerTypeDef = _GetRequiredType("System.Pointer", 0); + mReflectTypeIdTypeDef = _GetRequiredType("System.Reflection.TypeId"); mReflectArrayType = _GetRequiredType("System.Reflection.ArrayType"); mReflectFieldDataDef = _GetRequiredType("System.Reflection.TypeInstance.FieldData"); mReflectFieldSplatDataDef = _GetRequiredType("System.Reflection.TypeInstance.FieldSplatData"); diff --git a/IDEHelper/Compiler/BfCompiler.h b/IDEHelper/Compiler/BfCompiler.h index 6864590a..353fb9a4 100644 --- a/IDEHelper/Compiler/BfCompiler.h +++ b/IDEHelper/Compiler/BfCompiler.h @@ -374,9 +374,10 @@ public: BfTypeDef* mMethodRefTypeDef; BfTypeDef* mNullableTypeDef; - + BfTypeDef* mPointerTTypeDef; BfTypeDef* mPointerTypeDef; + BfTypeDef* mReflectTypeIdTypeDef; BfTypeDef* mReflectArrayType; BfTypeDef* mReflectFieldDataDef; BfTypeDef* mReflectFieldSplatDataDef; @@ -388,7 +389,7 @@ public: BfTypeDef* mReflectSizedArrayType; BfTypeDef* mReflectSpecializedGenericType; BfTypeDef* mReflectTypeInstanceTypeDef; - BfTypeDef* mReflectUnspecializedGenericType; + BfTypeDef* mReflectUnspecializedGenericType; BfTypeDef* mSizedArrayTypeDef; BfTypeDef* mAttributeTypeDef; diff --git a/IDEHelper/Compiler/BfExprEvaluator.cpp b/IDEHelper/Compiler/BfExprEvaluator.cpp index 47cd019e..d63fa9f2 100644 --- a/IDEHelper/Compiler/BfExprEvaluator.cpp +++ b/IDEHelper/Compiler/BfExprEvaluator.cpp @@ -3727,7 +3727,8 @@ BfTypedValue BfExprEvaluator::LookupIdentifier(BfAstNode* refNode, const StringI wantName = findName; while (wantName.StartsWith("@")) { - varSkipCount++; + if (wantName != "@return") + varSkipCount++; wantName.Remove(0); } } @@ -9942,7 +9943,10 @@ bool BfExprEvaluator::LookupTypeProp(BfTypeOfExpression* typeOfExpr, BfIdentifie else if (memberName == "IsSizedArray") _BoolResult(type->IsSizedArray()); else if (memberName == "TypeId") + { _Int32Result(type->mTypeId); + mResult.mType = mModule->ResolveTypeDef(mModule->mCompiler->mReflectTypeIdTypeDef); + } else if (memberName == "GenericParamCount") { auto genericTypeInst = type->ToGenericTypeInstance(); diff --git a/IDEHelper/Compiler/BfModule.cpp b/IDEHelper/Compiler/BfModule.cpp index 4585bfb0..96611b3b 100644 --- a/IDEHelper/Compiler/BfModule.cpp +++ b/IDEHelper/Compiler/BfModule.cpp @@ -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) { auto checkScope = mCurMethodState->mCurScope; @@ -5316,8 +5338,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin else typeDataVar = mBfIRBuilder->CreateConstNull(mBfIRBuilder->MapType(mContext->mBfTypeType)); - mTypeDataRefs[typeInstance] = typeDataVar; - + mTypeDataRefs[type] = typeDataVar; return typeDataVar; } @@ -6876,7 +6897,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin } typeDataVar = mBfIRBuilder->CreateBitCast(typeDataVar, mBfIRBuilder->MapType(mContext->mBfTypeType)); - mTypeDataRefs[typeInstance] = typeDataVar; + mTypeDataRefs[typeInstance] = typeDataVar; if ((!mIsComptimeModule) && (classVDataVar)) { @@ -13972,7 +13993,7 @@ void BfModule::CreateDIRetVal() } 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); } } @@ -14292,6 +14313,9 @@ void BfModule::EmitDeferredScopeCalls(bool useSrcPositions, BfScopeData* scopeDa { if (deferredCallEntry->mDeferredBlock != NULL) { + if (checkScope == &mCurMethodState->mHeadScope) + CreateRetValLocal(); + SetAndRestoreValue prevCustomAttribute(mCurMethodState->mEmitRefNode, deferredCallEntry->mEmitRefNode); VisitEmbeddedStatement(deferredCallEntry->mDeferredBlock, NULL, BfEmbeddedStatementFlags_IsDeferredBlock); } @@ -14374,12 +14398,15 @@ void BfModule::EmitDeferredScopeCalls(bool useSrcPositions, BfScopeData* scopeDa if (hasWork) { SetAndRestoreValue prevScope(mCurMethodState->mCurScope, checkScope); - + if (deferCloseNode != NULL) { UpdateSrcPos(deferCloseNode); } + if (checkScope == &mCurMethodState->mHeadScope) + CreateRetValLocal(); + if (doneBlock) { bool crossingMixin = mCurMethodState->mCurScope->mMixinDepth != checkScope->mMixinDepth; diff --git a/IDEHelper/Compiler/BfModule.h b/IDEHelper/Compiler/BfModule.h index 96e46852..b37a5dfc 100644 --- a/IDEHelper/Compiler/BfModule.h +++ b/IDEHelper/Compiler/BfModule.h @@ -1776,6 +1776,7 @@ public: BfLocalVariable* AddLocalVariableDef(BfLocalVariable* localVarDef, bool addDebugInfo = false, bool doAliasValue = false, BfIRValue declareBefore = BfIRValue(), BfIRInitType initType = BfIRInitType_NotSet); bool TryLocalVariableInit(BfLocalVariable* localVar); void LocalVariableDone(BfLocalVariable* localVar, bool isMethodExit); + void CreateRetValLocal(); void CreateDIRetVal(); BfTypedValue CreateTuple(const Array& values, const Array& fieldNames); void CheckTupleVariableDeclaration(BfTupleExpression* tupleExpr, BfType* initType); diff --git a/IDEHelper/Compiler/BfReducer.cpp b/IDEHelper/Compiler/BfReducer.cpp index b1d9f05c..b8492981 100644 --- a/IDEHelper/Compiler/BfReducer.cpp +++ b/IDEHelper/Compiler/BfReducer.cpp @@ -9768,11 +9768,12 @@ void BfReducer::HandleBlock(BfBlock* block, bool allowEndingExpression) flags = (CreateStmtFlags)(flags | CreateStmtFlags_AllowUnterminatedExpression); auto statement = CreateStatement(node, flags); - if (statement == NULL) + if ((statement == NULL) && (mSource != NULL)) statement = mSource->CreateErrorNode(node); isDone = !mVisitorPos.MoveNext(); - mVisitorPos.Write(statement); + if (statement != NULL) + mVisitorPos.Write(statement); } mVisitorPos.Trim(); diff --git a/IDEHelper/Compiler/CeMachine.cpp b/IDEHelper/Compiler/CeMachine.cpp index ed809425..b79045c2 100644 --- a/IDEHelper/Compiler/CeMachine.cpp +++ b/IDEHelper/Compiler/CeMachine.cpp @@ -2861,11 +2861,11 @@ addr_ce CeContext::GetReflectType(int typeId) ceModule->PopulateType(bfType, BfPopulateType_DataAndMethods); Dictionary usedStringMap; - auto irData = ceModule->CreateTypeData(bfType, usedStringMap, true, true, true, false); + auto irData = ceModule->CreateTypeData(bfType, usedStringMap, true, true, true, false); BeValue* beValue = NULL; if (auto constant = mCeMachine->mCeModule->mBfIRBuilder->GetConstant(irData)) - { + { if (constant->mConstType == BfConstType_BitCast) { auto bitcast = (BfConstantBitCast*)constant; @@ -2875,12 +2875,13 @@ addr_ce CeContext::GetReflectType(int typeId) { auto globalVar = (BfGlobalVar*)constant; beValue = mCeMachine->mCeModule->mBfIRBuilder->mBeIRCodeGen->GetBeValue(globalVar->mStreamId); - } + } } - - if (auto constant = BeValueDynCast(beValue)) + + if (auto constant = BeValueDynCast(beValue)) *addrPtr = GetConstantData(constant); + // We need to 'get' again because we might have resized return *addrPtr; } @@ -4103,9 +4104,8 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* { int32 size = *(int32*)((uint8*)stackPtr + 4); CE_CHECKALLOC(size); - uint8* ptr = CeMalloc(size); - addr_ce& result = *(addr_ce*)((uint8*)stackPtr + 0); - result = (addr_ce)(ptr - memStart); + uint8* ptr = CeMalloc(size); + CeSetAddrVal(stackPtr + 0, ptr - memStart, ptrSize); handled = true; return true; } @@ -4185,7 +4185,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* auto reflectType = GetReflectType(typeId); _FixVariables(); - *(addr_ce*)(stackPtr + 0) = reflectType; + CeSetAddrVal(stackPtr + 0, reflectType, ptrSize); handled = true; return true; } @@ -4194,7 +4194,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* int32 typeId = *(int32*)((uint8*)stackPtr + ceModule->mSystem->mPtrSize); auto reflectType = GetReflectType(typeId); _FixVariables(); - *(addr_ce*)(stackPtr + 0) = reflectType; + CeSetAddrVal(stackPtr + 0, reflectType, ptrSize); handled = true; return true; } @@ -4209,7 +4209,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* } auto reflectType = GetReflectType(typeName); _FixVariables(); - *(addr_ce*)(stackPtr + 0) = reflectType; + CeSetAddrVal(stackPtr + 0, reflectType, ptrSize); handled = true; return true; } @@ -4220,7 +4220,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* auto reflectType = GetReflectSpecializedType(typeAddr, typeSpan); _FixVariables(); - *(addr_ce*)(stackPtr + 0) = reflectType; + CeSetAddrVal(stackPtr + 0, reflectType, ptrSize); handled = true; return true; } @@ -4348,10 +4348,11 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* return false; } + addr_ce stringAddr = GetString(methodInstance->GetParamName(paramIdx)); + _FixVariables(); *(int32*)(stackPtr + 0) = methodInstance->GetParamType(paramIdx)->mTypeId; *(int16*)(stackPtr + 4) = 0; // Flags - CeSetAddrVal(stackPtr + 4+2, GetString(methodInstance->GetParamName(paramIdx)), ptrSize); - _FixVariables(); + CeSetAddrVal(stackPtr + 4+2, stringAddr, ptrSize); handled = true; return true; } diff --git a/IDEHelper/Tests/src/Comptime.bf b/IDEHelper/Tests/src/Comptime.bf index d6a290ac..c2a13b21 100644 --- a/IDEHelper/Tests/src/Comptime.bf +++ b/IDEHelper/Tests/src/Comptime.bf @@ -48,8 +48,20 @@ namespace Tests String emit = scope $"LogAttribute.gLog.AppendF($\"Called {method}"; for (var fieldIdx < method.ParamCount) emit.AppendF($" {{ {method.GetParamName(fieldIdx)} }}"); - emit.Append("\");"); + emit.Append("\\n\");"); 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] - public static void MethodA(int a, int b) + enum MethodAErr { + ErrorA, + ErrorB + } + [Log] + static Result MethodA(int a, int b) + { + return .Err(.ErrorB); } static Type GetBiggerType(Type t) @@ -104,8 +122,9 @@ namespace Tests Compiler.Mixin("int 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); Test.Assert(v0.GetType() == typeof(int16));