diff --git a/BeefLibs/corlib/src/Diagnostics/Debug.bf b/BeefLibs/corlib/src/Diagnostics/Debug.bf index dd4bb851..fbc05536 100644 --- a/BeefLibs/corlib/src/Diagnostics/Debug.bf +++ b/BeefLibs/corlib/src/Diagnostics/Debug.bf @@ -25,7 +25,7 @@ namespace System.Diagnostics #if !DEBUG [SkipCall] #endif - public static void FatalError(String msg = "Fatal error encountered", String filePath = Compiler.CallerFilePath, int line = Compiler.CallerLineNum) + public static void FatalError(StringView msg = "Fatal error encountered", String filePath = Compiler.CallerFilePath, int line = Compiler.CallerLineNum) { String failStr = scope .()..Append(msg, " at line "); line.ToString(failStr); @@ -59,7 +59,7 @@ namespace System.Diagnostics Write(sv.[Friend]mPtr, sv.[Friend]mLength); } - public static void Write(String fmt, params Span args) + public static void Write(StringView fmt, params Span args) { String str = scope String(4096); str.AppendF(fmt, params args); @@ -86,7 +86,7 @@ namespace System.Diagnostics Write(lineStr.Ptr, lineStr.Length); } - public static void WriteLine(StringView strFormat, params Object[] args) + public static void WriteLine(StringView strFormat, params Span args) { String paramStr = scope String(4096); paramStr.AppendF(strFormat, params args); diff --git a/BeefLibs/corlib/src/Type.bf b/BeefLibs/corlib/src/Type.bf index 4101cc93..d28ff5c9 100644 --- a/BeefLibs/corlib/src/Type.bf +++ b/BeefLibs/corlib/src/Type.bf @@ -5,6 +5,163 @@ using System.Diagnostics; namespace System { + public class TypeDeclaration + { + protected TypeId mTypeId; + protected TypeId mBaseTypeId; + protected TypeId mOuterTypeId; + protected TypeFlags mTypeFlags; + protected TypeCode mTypeCode; + + public TypeCode TypeCode => mTypeCode; + public TypeId TypeId => mTypeId; + public TypeDeclaration BaseType + { + get + { + return Type.[Friend]Comptime_GetTypeDeclarationById((.)mBaseTypeId); + } + } + public TypeDeclaration OuterType + { + get + { + return Type.[Friend]Comptime_GetTypeDeclarationById((.)mOuterTypeId); + } + } + public Type ResolvedType => Type.[Friend]Comptime_GetTypeById((.)mTypeId); + + public static Enumerator Types + { + get + { + return .(); + } + } + + public void GetFullName(String strBuffer) + { + strBuffer.Append(Type.[Friend]Comptime_Type_ToString((.)mTypeId)); + } + + public void GetName(String strBuffer) + { + strBuffer.Append(Type.[Friend]Comptime_TypeName_ToString((.)mTypeId)); + } + + public void GetNamespace(String strBuffer) + { + strBuffer.Append(Type.[Friend]Comptime_Namespace_ToString((.)mTypeId)); + } + + public bool HasCustomAttribute() where T : Attribute + { + if (Compiler.IsComptime) + { + int32 attrIdx = -1; + Type attrType = null; + repeat + { + attrType = Type.[Friend]Comptime_Type_GetCustomAttributeType((int32)TypeId, ++attrIdx); + if (attrType == typeof(T)) + return true; + } + while (attrType != null); + return false; + } + return false; + } + + public Result GetCustomAttribute() where T : Attribute + { + if (Compiler.IsComptime) + { + int32 attrIdx = -1; + Type attrType = null; + repeat + { + attrType = Type.[Friend]Comptime_Type_GetCustomAttributeType((int32)TypeId, ++attrIdx); + if (attrType == typeof(T)) + { + T val = ?; + if (Type.[Friend]Comptime_Type_GetCustomAttribute((int32)TypeId, attrIdx, &val)) + return val; + } + } + while (attrType != null); + return .Err; + } + return .Err; + } + + [Comptime] + public AttributeInfo.ComptimeTypeCustomAttributeEnumerator GetCustomAttributes() + { + return .((int32)TypeId); + } + + public struct Enumerator : IEnumerator + { + int32 mCurId; + + public Result GetNext() mut + { + while (true) + { + if (!Compiler.IsComptime) + { + Runtime.FatalError("Runtime type declarations are not supported"); + } + else + { + var typeDecl = Type.[Friend]Comptime_GetNextTypeDeclaration(mCurId); + if (typeDecl != null) + { + mCurId = (.)typeDecl.TypeId; + return .Ok(typeDecl); + } + return .Err; + } + } + } + } + + public static TypeDeclaration GetById(TypeId typeId) => Type.[Friend]Comptime_GetTypeDeclarationById((.)typeId); + + public static Result GetByName(StringView typeName) + { + if (Compiler.IsComptime) + { + var type = Type.[Friend]Comptime_GetTypeDeclarationByName(typeName); + if (type == null) + return .Err; + return type; + } + + return .Err; + } + + public override void ToString(String strBuffer) + { + GetFullName(strBuffer); + } + + public bool HasDeclaredField(StringView fieldName) + { + return Type.[Friend]Comptime_Type_HasDeclaredMember((.)mTypeId, 0, fieldName); + } + + public bool HasDeclaredMethod(StringView fieldName) + { + return Type.[Friend]Comptime_Type_HasDeclaredMember((.)mTypeId, 1, fieldName); + } + + public bool HasDeclaredProperty(StringView fieldName) + { + return Type.[Friend]Comptime_Type_HasDeclaredMember((.)mTypeId, 2, fieldName); + } + } + struct ClassVData { public int mType; @@ -32,6 +189,21 @@ namespace System protected uint8 mAlign; protected uint8 mAllocStackCountOverride; + public TypeDeclaration TypeDeclaration + { + get + { + if (!Compiler.IsComptime) + { + Runtime.FatalError("Runtime type declarations are not supported"); + } + else + { + return Comptime_GetTypeDeclarationById((.)mTypeId); + } + } + } + public static TypeId TypeIdEnd { get @@ -551,9 +723,15 @@ namespace System public int64 mData; } + static extern TypeDeclaration Comptime_GetTypeDeclarationById(int32 typeId); + static extern TypeDeclaration Comptime_GetTypeDeclarationByName(StringView name); + static extern TypeDeclaration Comptime_GetNextTypeDeclaration(int32 lastTypeId); + static extern bool Comptime_Type_HasDeclaredMember(int32 typeId, int32 kind, StringView name); static extern Type Comptime_GetTypeById(int32 typeId); static extern Type Comptime_GetTypeByName(StringView name); static extern String Comptime_Type_ToString(int32 typeId); + static extern String Comptime_TypeName_ToString(int32 typeId); + static extern String Comptime_Namespace_ToString(int32 typeId); static extern Type Comptime_GetSpecializedType(Type unspecializedType, Span typeArgs); static extern bool Comptime_Type_GetCustomAttribute(int32 typeId, int32 attributeIdx, void* dataPtr); static extern bool Comptime_Field_GetCustomAttribute(int32 typeId, int32 fieldIdx, int32 attributeIdx, void* dataPtr); @@ -766,7 +944,7 @@ namespace System while (true) { if (Compiler.IsComptime) - Runtime.FatalError("Comptime type enumeration not supported"); + Runtime.FatalError("Comptime type enumeration not supported. Consider enumerating over TypeDeclaration.Types"); if (mCurId >= sTypeCount) return .Err; @@ -838,7 +1016,13 @@ namespace System namespace System.Reflection { - public struct TypeId : int32 {} + public struct TypeId : int32 + { + public override void ToString(String strBuffer) + { + strBuffer.AppendF($"TypeId#{(int32)this}"); + } + } [Ordered, AlwaysInclude(AssumeInstantiated=true)] public class TypeInstance : Type @@ -1409,7 +1593,11 @@ namespace System.Reflection { if (i > 0) strBuffer.Append(", "); - Type.GetType(mResolvedTypeRefs[i]).GetFullName(strBuffer); + var genericArg = Type.GetType(mResolvedTypeRefs[i]); + if (genericArg != null) + genericArg.GetFullName(strBuffer); + else + strBuffer.Append("???"); } strBuffer.Append('>'); } diff --git a/IDE/mintest/minlib/src/System/Type.bf b/IDE/mintest/minlib/src/System/Type.bf index 2a9fb9dd..e6c2eef7 100644 --- a/IDE/mintest/minlib/src/System/Type.bf +++ b/IDE/mintest/minlib/src/System/Type.bf @@ -15,6 +15,15 @@ namespace System // including the vtable and interface slots } + public class TypeDeclaration + { + protected TypeId mTypeId; + protected TypeId mBaseTypeId; + protected TypeId mOuterTypeId; + protected TypeFlags mTypeFlags; + protected TypeCode mTypeCode; + } + [Ordered, AlwaysInclude(AssumeInstantiated=true)] public class Type { diff --git a/IDEHelper/Compiler/BfCompiler.cpp b/IDEHelper/Compiler/BfCompiler.cpp index a0b18358..28eb0bd5 100644 --- a/IDEHelper/Compiler/BfCompiler.cpp +++ b/IDEHelper/Compiler/BfCompiler.cpp @@ -474,6 +474,7 @@ BfCompiler::BfCompiler(BfSystem* bfSystem, bool isResolveOnly) mStringTypeDef = NULL; mStringViewTypeDef = NULL; mThreadStaticAttributeTypeDef = NULL; + mTypeTypeDeclDef = NULL; mTypeTypeDef = NULL; mUnboundAttributeTypeDef = NULL; mValueTypeTypeDef = NULL; @@ -7326,6 +7327,7 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory) mStringViewTypeDef = _GetRequiredType("System.StringView"); mTestAttributeTypeDef = _GetRequiredType("System.TestAttribute"); mThreadStaticAttributeTypeDef = _GetRequiredType("System.ThreadStaticAttribute"); + mTypeTypeDeclDef = _GetRequiredType("System.TypeDeclaration"); mTypeTypeDef = _GetRequiredType("System.Type"); mUnboundAttributeTypeDef = _GetRequiredType("System.UnboundAttribute"); mValueTypeTypeDef = _GetRequiredType("System.ValueType"); diff --git a/IDEHelper/Compiler/BfCompiler.h b/IDEHelper/Compiler/BfCompiler.h index 2cdc6f1e..906dfe1e 100644 --- a/IDEHelper/Compiler/BfCompiler.h +++ b/IDEHelper/Compiler/BfCompiler.h @@ -376,6 +376,7 @@ public: BfTypeDef* mEnumTypeDef; BfTypeDef* mStringTypeDef; BfTypeDef* mStringViewTypeDef; + BfTypeDef* mTypeTypeDeclDef; BfTypeDef* mTypeTypeDef; BfTypeDef* mValueTypeTypeDef; BfTypeDef* mResultTypeDef; diff --git a/IDEHelper/Compiler/BfExprEvaluator.cpp b/IDEHelper/Compiler/BfExprEvaluator.cpp index 61246e4d..c96e0eab 100644 --- a/IDEHelper/Compiler/BfExprEvaluator.cpp +++ b/IDEHelper/Compiler/BfExprEvaluator.cpp @@ -12005,7 +12005,9 @@ bool BfExprEvaluator::LookupTypeProp(BfTypeOfExpression* typeOfExpr, BfIdentifie } mModule->AddDependency(type, mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_ExprTypeReference); - mModule->PopulateType(type); + + // We want to try to avoid triggering OnTypeInit for basic info + mModule->PopulateType(type, BfPopulateType_Interfaces_Direct); auto typeInstance = type->ToTypeInstance(); auto _BoolResult = [&](bool val) @@ -12072,214 +12074,220 @@ bool BfExprEvaluator::LookupTypeProp(BfTypeOfExpression* typeOfExpr, BfIdentifie auto genericTypeInst = type->ToGenericTypeInstance(); _Int32Result((genericTypeInst != NULL) ? (int)genericTypeInst->mGenericTypeInfo->mTypeGenericArguments.size() : 0); } - else if (memberName == "Size") - _Int32Result(type->mSize); - else if (memberName == "Align") - _Int32Result(type->mAlign); - else if (memberName == "Stride") - _Int32Result(type->GetStride()); - else if (memberName == "InstanceSize") - _Int32Result((typeInstance != NULL) ? typeInstance->mInstSize : type->mSize); - else if (memberName == "InstanceAlign") - _Int32Result((typeInstance != NULL) ? typeInstance->mInstAlign : type->mSize); - else if (memberName == "InstanceStride") - _Int32Result((typeInstance != NULL) ? typeInstance->GetInstStride() : type->GetStride()); - else if (memberName == "UnderlyingType") + else { - bool handled = false; + // We need full data + mModule->PopulateType(type, BfPopulateType_Data); - auto typeType = mModule->ResolveTypeDef(mModule->mCompiler->mTypeTypeDef); - if (type->IsGenericParam()) + if (memberName == "Size") + _Int32Result(type->mSize); + else if (memberName == "Align") + _Int32Result(type->mAlign); + else if (memberName == "Stride") + _Int32Result(type->GetStride()); + else if (memberName == "InstanceSize") + _Int32Result((typeInstance != NULL) ? typeInstance->mInstSize : type->mSize); + else if (memberName == "InstanceAlign") + _Int32Result((typeInstance != NULL) ? typeInstance->mInstAlign : type->mSize); + else if (memberName == "InstanceStride") + _Int32Result((typeInstance != NULL) ? typeInstance->GetInstStride() : type->GetStride()); + else if (memberName == "UnderlyingType") { - auto genericParamInstance = mModule->GetGenericParamInstance((BfGenericParamType*)type); - if (genericParamInstance->IsEnum()) + bool handled = false; + + auto typeType = mModule->ResolveTypeDef(mModule->mCompiler->mTypeTypeDef); + if (type->IsGenericParam()) { - handled = true; - mResult = BfTypedValue(mModule->mBfIRBuilder->GetUndefConstValue(mModule->mBfIRBuilder->MapType(typeType)), typeType); - } - } - else if (type->IsEnum()) - { - if (type->IsDataIncomplete()) - mModule->PopulateType(type); - auto underlyingType = type->GetUnderlyingType(); - if (underlyingType != NULL) - { - handled = true; - mModule->AddDependency(underlyingType, mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_ExprTypeReference); - mResult = BfTypedValue(mModule->CreateTypeDataRef(underlyingType), typeType); - } - } - - if (!handled) - mResult = BfTypedValue(mModule->CreateTypeDataRef(mModule->GetPrimitiveType(BfTypeCode_None)), typeType); - } - else if (memberName == "BitSize") - { - auto int32Type = mModule->GetPrimitiveType(BfTypeCode_Int32); - - BfType* checkType = type; - if (checkType->IsTypedPrimitive()) - checkType = checkType->GetUnderlyingType(); - - if (checkType->IsGenericParam()) - { - mResult = mModule->GetDefaultTypedValue(int32Type, false, Beefy::BfDefaultValueKind_Undef); - return true; - } - - if ((typeInstance != NULL) && (typeInstance->IsEnum())) - { - if (typeInstance->mTypeInfoEx != NULL) - { - int64 minValue = typeInstance->mTypeInfoEx->mMinValue; - if (minValue < 0) - minValue = ~minValue; - int64 maxValue = typeInstance->mTypeInfoEx->mMaxValue; - if (maxValue < 0) - maxValue = ~maxValue; - uint64 value = (uint64)minValue | (uint64)maxValue; - - int bitCount = 1; - if (typeInstance->mTypeInfoEx->mMinValue < 0) - bitCount++; - - while (value >>= 1) - bitCount++; - - mModule->AddDependency(typeInstance, mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_ReadFields); - mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(BfTypeCode_Int32, bitCount), int32Type); - return true; - } - } - - int bitSize = checkType->mSize * 8; - if (checkType->GetTypeCode() == BfTypeCode_Boolean) - bitSize = 1; - mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(BfTypeCode_Int32, bitSize), int32Type); - return true; - } - else if ((memberName == "MinValue") || (memberName == "MaxValue")) - { - bool isMin = memberName == "MinValue"; - bool isBitSize = memberName == "BitSize"; - - BfType* checkType = type; - if (checkType->IsTypedPrimitive()) - checkType = checkType->GetUnderlyingType(); - - if (checkType->IsGenericParam()) - { - bool foundMatch = false; - - auto genericParamInstance = mModule->GetGenericParamInstance((BfGenericParamType*)checkType); - if (((genericParamInstance->mGenericParamFlags & BfGenericParamFlag_Enum) != 0) || - ((genericParamInstance->mTypeConstraint != NULL) && (genericParamInstance->mTypeConstraint->IsInstanceOf(mModule->mCompiler->mEnumTypeDef)))) - foundMatch = true; - - else - { - for (auto constraint : genericParamInstance->mInterfaceConstraints) + auto genericParamInstance = mModule->GetGenericParamInstance((BfGenericParamType*)type); + if (genericParamInstance->IsEnum()) { - if (constraint->IsInstanceOf(mModule->mCompiler->mIIntegerTypeDef)) - foundMatch = true; + handled = true; + mResult = BfTypedValue(mModule->mBfIRBuilder->GetUndefConstValue(mModule->mBfIRBuilder->MapType(typeType)), typeType); + } + } + else if (type->IsEnum()) + { + if (type->IsDataIncomplete()) + mModule->PopulateType(type); + auto underlyingType = type->GetUnderlyingType(); + if (underlyingType != NULL) + { + handled = true; + mModule->AddDependency(underlyingType, mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_ExprTypeReference); + mResult = BfTypedValue(mModule->CreateTypeDataRef(underlyingType), typeType); } } - if ((mModule->mCurMethodInstance != NULL) && (mModule->mCurMethodInstance->mIsUnspecialized) && (mModule->mCurMethodInstance->mMethodInfoEx != NULL)) - { - for (int genericParamIdx = (int)mModule->mCurMethodInstance->mMethodInfoEx->mMethodGenericArguments.size(); - genericParamIdx < mModule->mCurMethodInstance->mMethodInfoEx->mGenericParams.size(); genericParamIdx++) - { - genericParamInstance = mModule->mCurMethodInstance->mMethodInfoEx->mGenericParams[genericParamIdx]; - if (genericParamInstance->mExternType == type) - { - if (((genericParamInstance->mGenericParamFlags & BfGenericParamFlag_Enum) != 0) || - ((genericParamInstance->mTypeConstraint != NULL) && (genericParamInstance->mTypeConstraint->IsInstanceOf(mModule->mCompiler->mEnumTypeDef)))) - foundMatch = true; - } - } - } + if (!handled) + mResult = BfTypedValue(mModule->CreateTypeDataRef(mModule->GetPrimitiveType(BfTypeCode_None)), typeType); + } + else if (memberName == "BitSize") + { + auto int32Type = mModule->GetPrimitiveType(BfTypeCode_Int32); - if (foundMatch) + BfType* checkType = type; + if (checkType->IsTypedPrimitive()) + checkType = checkType->GetUnderlyingType(); + + if (checkType->IsGenericParam()) { - mResult = mModule->GetDefaultTypedValue(type, false, Beefy::BfDefaultValueKind_Undef); + mResult = mModule->GetDefaultTypedValue(int32Type, false, Beefy::BfDefaultValueKind_Undef); return true; } - } - - if (checkType->IsPrimitiveType()) - { - auto primType = (BfPrimitiveType*)checkType; if ((typeInstance != NULL) && (typeInstance->IsEnum())) { if (typeInstance->mTypeInfoEx != NULL) { + int64 minValue = typeInstance->mTypeInfoEx->mMinValue; + if (minValue < 0) + minValue = ~minValue; + int64 maxValue = typeInstance->mTypeInfoEx->mMaxValue; + if (maxValue < 0) + maxValue = ~maxValue; + uint64 value = (uint64)minValue | (uint64)maxValue; + + int bitCount = 1; + if (typeInstance->mTypeInfoEx->mMinValue < 0) + bitCount++; + + while (value >>= 1) + bitCount++; + mModule->AddDependency(typeInstance, mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_ReadFields); - mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(primType->mTypeDef->mTypeCode, isMin ? (uint64)typeInstance->mTypeInfoEx->mMinValue : (uint64)typeInstance->mTypeInfoEx->mMaxValue), typeInstance); + mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(BfTypeCode_Int32, bitCount), int32Type); return true; } } + + int bitSize = checkType->mSize * 8; + if (checkType->GetTypeCode() == BfTypeCode_Boolean) + bitSize = 1; + mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(BfTypeCode_Int32, bitSize), int32Type); + return true; + } + else if ((memberName == "MinValue") || (memberName == "MaxValue")) + { + bool isMin = memberName == "MinValue"; + bool isBitSize = memberName == "BitSize"; + + BfType* checkType = type; + if (checkType->IsTypedPrimitive()) + checkType = checkType->GetUnderlyingType(); + + if (checkType->IsGenericParam()) + { + bool foundMatch = false; + + auto genericParamInstance = mModule->GetGenericParamInstance((BfGenericParamType*)checkType); + if (((genericParamInstance->mGenericParamFlags & BfGenericParamFlag_Enum) != 0) || + ((genericParamInstance->mTypeConstraint != NULL) && (genericParamInstance->mTypeConstraint->IsInstanceOf(mModule->mCompiler->mEnumTypeDef)))) + foundMatch = true; + + else + { + for (auto constraint : genericParamInstance->mInterfaceConstraints) + { + if (constraint->IsInstanceOf(mModule->mCompiler->mIIntegerTypeDef)) + foundMatch = true; + } + } + + if ((mModule->mCurMethodInstance != NULL) && (mModule->mCurMethodInstance->mIsUnspecialized) && (mModule->mCurMethodInstance->mMethodInfoEx != NULL)) + { + for (int genericParamIdx = (int)mModule->mCurMethodInstance->mMethodInfoEx->mMethodGenericArguments.size(); + genericParamIdx < mModule->mCurMethodInstance->mMethodInfoEx->mGenericParams.size(); genericParamIdx++) + { + genericParamInstance = mModule->mCurMethodInstance->mMethodInfoEx->mGenericParams[genericParamIdx]; + if (genericParamInstance->mExternType == type) + { + if (((genericParamInstance->mGenericParamFlags & BfGenericParamFlag_Enum) != 0) || + ((genericParamInstance->mTypeConstraint != NULL) && (genericParamInstance->mTypeConstraint->IsInstanceOf(mModule->mCompiler->mEnumTypeDef)))) + foundMatch = true; + } + } + } + + if (foundMatch) + { + mResult = mModule->GetDefaultTypedValue(type, false, Beefy::BfDefaultValueKind_Undef); + return true; + } + } + + if (checkType->IsPrimitiveType()) + { + auto primType = (BfPrimitiveType*)checkType; + + if ((typeInstance != NULL) && (typeInstance->IsEnum())) + { + if (typeInstance->mTypeInfoEx != NULL) + { + mModule->AddDependency(typeInstance, mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_ReadFields); + mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(primType->mTypeDef->mTypeCode, isMin ? (uint64)typeInstance->mTypeInfoEx->mMinValue : (uint64)typeInstance->mTypeInfoEx->mMaxValue), typeInstance); + return true; + } + } + else + { + switch (primType->mTypeDef->mTypeCode) + { + case BfTypeCode_Int8: + mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(primType->mTypeDef->mTypeCode, isMin ? -0x80 : 0x7F), primType); + return true; + case BfTypeCode_Int16: + mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(primType->mTypeDef->mTypeCode, isMin ? -0x8000 : 0x7FFF), primType); + return true; + case BfTypeCode_Int32: + mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(primType->mTypeDef->mTypeCode, isMin ? (uint64)-0x80000000LL : 0x7FFFFFFF), primType); + return true; + case BfTypeCode_Int64: + mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(primType->mTypeDef->mTypeCode, isMin ? (uint64)-0x8000000000000000LL : (uint64)0x7FFFFFFFFFFFFFFFLL), primType); + return true; + case BfTypeCode_UInt8: + case BfTypeCode_Char8: + mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(primType->mTypeDef->mTypeCode, isMin ? 0 : 0xFF), primType); + return true; + case BfTypeCode_UInt16: + case BfTypeCode_Char16: + mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(primType->mTypeDef->mTypeCode, isMin ? 0 : 0xFFFF), primType); + return true; + case BfTypeCode_UInt32: + case BfTypeCode_Char32: + mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(primType->mTypeDef->mTypeCode, isMin ? 0 : (uint64)0xFFFFFFFFLL), primType); + return true; + case BfTypeCode_UInt64: + mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(primType->mTypeDef->mTypeCode, isMin ? 0 : (uint64)0xFFFFFFFFFFFFFFFFLL), primType); + return true; + case BfTypeCode_IntPtr: + if (mModule->mSystem->mPtrSize == 8) + mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(primType->mTypeDef->mTypeCode, isMin ? (uint64)-0x8000000000000000LL : (uint64)0x7FFFFFFFFFFFFFFFLL), primType); + else + mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(primType->mTypeDef->mTypeCode, isMin ? (uint64)-0x80000000LL : 0x7FFFFFFF), primType); + return true; + case BfTypeCode_UIntPtr: + if (mModule->mSystem->mPtrSize == 8) + mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(primType->mTypeDef->mTypeCode, isMin ? 0 : (uint64)0xFFFFFFFFFFFFFFFFLL), primType); + else + mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(primType->mTypeDef->mTypeCode, isMin ? 0 : (uint64)0xFFFFFFFFLL), primType); + return true; + default: break; + } + } + } + + if (type->IsEnum()) + { + mModule->Fail(StrFormat("'MinValue' cannot be used on enum with payload '%s'", mModule->TypeToString(type).c_str()), propName); + } else { - switch (primType->mTypeDef->mTypeCode) - { - case BfTypeCode_Int8: - mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(primType->mTypeDef->mTypeCode, isMin ? -0x80 : 0x7F), primType); - return true; - case BfTypeCode_Int16: - mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(primType->mTypeDef->mTypeCode, isMin ? -0x8000 : 0x7FFF), primType); - return true; - case BfTypeCode_Int32: - mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(primType->mTypeDef->mTypeCode, isMin ? (uint64)-0x80000000LL : 0x7FFFFFFF), primType); - return true; - case BfTypeCode_Int64: - mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(primType->mTypeDef->mTypeCode, isMin ? (uint64)-0x8000000000000000LL : (uint64)0x7FFFFFFFFFFFFFFFLL), primType); - return true; - case BfTypeCode_UInt8: - case BfTypeCode_Char8: - mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(primType->mTypeDef->mTypeCode, isMin ? 0 : 0xFF), primType); - return true; - case BfTypeCode_UInt16: - case BfTypeCode_Char16: - mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(primType->mTypeDef->mTypeCode, isMin ? 0 : 0xFFFF), primType); - return true; - case BfTypeCode_UInt32: - case BfTypeCode_Char32: - mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(primType->mTypeDef->mTypeCode, isMin ? 0 : (uint64)0xFFFFFFFFLL), primType); - return true; - case BfTypeCode_UInt64: - mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(primType->mTypeDef->mTypeCode, isMin ? 0 : (uint64)0xFFFFFFFFFFFFFFFFLL), primType); - return true; - case BfTypeCode_IntPtr: - if (mModule->mSystem->mPtrSize == 8) - mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(primType->mTypeDef->mTypeCode, isMin ? (uint64)-0x8000000000000000LL : (uint64)0x7FFFFFFFFFFFFFFFLL), primType); - else - mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(primType->mTypeDef->mTypeCode, isMin ? (uint64)-0x80000000LL : 0x7FFFFFFF), primType); - return true; - case BfTypeCode_UIntPtr: - if (mModule->mSystem->mPtrSize == 8) - mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(primType->mTypeDef->mTypeCode, isMin ? 0 : (uint64)0xFFFFFFFFFFFFFFFFLL), primType); - else - mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(primType->mTypeDef->mTypeCode, isMin ? 0 : (uint64)0xFFFFFFFFLL), primType); - return true; - default: break; - } + mModule->Fail(StrFormat("'%s' cannot be used on type '%s'", memberName.c_str(), mModule->TypeToString(type).c_str()), propName); } } - - if (type->IsEnum()) - { - mModule->Fail(StrFormat("'MinValue' cannot be used on enum with payload '%s'", mModule->TypeToString(type).c_str()), propName); - } else - { - mModule->Fail(StrFormat("'%s' cannot be used on type '%s'", memberName.c_str(), mModule->TypeToString(type).c_str()), propName); - } + return false; } - else - return false; if ((type->IsGenericParam()) && (!mModule->mIsComptimeModule)) { diff --git a/IDEHelper/Compiler/BfModule.cpp b/IDEHelper/Compiler/BfModule.cpp index 90882d21..2912e599 100644 --- a/IDEHelper/Compiler/BfModule.cpp +++ b/IDEHelper/Compiler/BfModule.cpp @@ -6004,29 +6004,13 @@ void BfModule::CreateSlotOfs(BfTypeInstance* typeInstance) GetConstValue32(virtSlotIdx), slotVarName); } -BfIRValue BfModule::CreateTypeData(BfType* type, BfCreateTypeDataContext& ctx, bool forceReflectFields, bool needsTypeData, bool needsTypeNames, bool needsVData) +BfIRValue BfModule::GetTypeTypeData(BfType* type, BfCreateTypeDataContext& ctx, bool needsTypeData, bool wantsTypeDecl, bool needsTypeNames, int& typeFlags, int& typeCode) { - if ((IsHotCompile()) && (!type->mDirty)) - return BfIRValue(); - - BfIRValue* irValuePtr = NULL; - if (mTypeDataRefs.TryGetValue(type, &irValuePtr)) - { - return *irValuePtr; - } - BfTypeInstance* typeInstance = type->ToTypeInstance(); BfType* typeInstanceType = ResolveTypeDef(mCompiler->mReflectTypeInstanceTypeDef); mBfIRBuilder->PopulateType(typeInstanceType, BfIRPopulateType_Full_ForceDefinition); - if (typeInstanceType == NULL) - { - AssertErrorState(); - return BfIRValue(); - } - - BfIRValue typeTypeData; - int typeFlags = 0; + BfIRValue typeTypeData; if (needsTypeData) { BfTypeInstance* typeInstanceTypeInstance = typeInstanceType->ToTypeInstance(); @@ -6069,10 +6053,15 @@ BfIRValue BfModule::CreateTypeData(BfType* type, BfCreateTypeDataContext& ctx, b else typeDataSource = mContext->mBfTypeType; + if (wantsTypeDecl) + { + typeDataSource = ResolveTypeDef(mCompiler->mTypeTypeDeclDef)->ToTypeInstance(); + } + if ((!mTypeDataRefs.ContainsKey(typeDataSource)) && (typeDataSource != type) && (!mIsComptimeModule)) { CreateTypeData(typeDataSource, ctx, false, true, needsTypeNames, true); - } + } typeTypeData = CreateClassVDataGlobal(typeDataSource); @@ -6084,40 +6073,6 @@ BfIRValue BfModule::CreateTypeData(BfType* type, BfCreateTypeDataContext& ctx, b typeTypeData = mBfIRBuilder->CreateConstNull(); } - BfType* longType = GetPrimitiveType(BfTypeCode_Int64); - BfType* intType = GetPrimitiveType(BfTypeCode_Int32); - BfType* intPtrType = GetPrimitiveType(BfTypeCode_IntPtr); - BfType* shortType = GetPrimitiveType(BfTypeCode_Int16); - BfType* byteType = GetPrimitiveType(BfTypeCode_Int8); - - BfType* typeIdType = intType; - - auto voidPtrType = GetPrimitiveType(BfTypeCode_NullPtr); - auto voidPtrIRType = mBfIRBuilder->MapType(voidPtrType); - auto voidPtrPtrIRType = mBfIRBuilder->GetPointerTo(voidPtrIRType); - auto voidPtrNull = GetDefaultValue(voidPtrType); - - SizedArray typeValueParams; - GetConstClassValueParam(typeTypeData, typeValueParams); - - FixConstValueParams(mContext->mBfObjectType, typeValueParams); - BfIRValue objectData = mBfIRBuilder->CreateConstAgg_Value(mBfIRBuilder->MapTypeInst(mContext->mBfObjectType, BfIRPopulateType_Full), typeValueParams); - - StringT<512> typeDataName; - if ((typeInstance != NULL) && (!typeInstance->IsTypeAlias())) - { - BfMangler::MangleStaticFieldName(typeDataName, mCompiler->GetMangleKind(), typeInstance, "sBfTypeData"); - if (typeInstance->mTypeDef->IsGlobalsContainer()) - typeDataName += "`G`" + typeInstance->mTypeDef->mProject->mName; - } - else - { - typeDataName += "sBfTypeData."; - BfMangler::Mangle(typeDataName, mCompiler->GetMangleKind(), type, mContext->mScratchModule); - } - - int typeCode = BfTypeCode_None; - if (typeInstance != NULL) { BF_ASSERT((type->mDefineState >= BfTypeDefineState_DefinedAndMethodsSlotted) || mIsComptimeModule); @@ -6181,7 +6136,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, BfCreateTypeDataContext& ctx, b typeFlags |= BfTypeFlags_Delegate; if (type->IsFunction()) typeFlags |= BfTypeFlags_Function; - if ((type->mDefineState != BfTypeDefineState_CETypeInit) && (type->WantsGCMarking())) + if ((!wantsTypeDecl) && (type->mDefineState != BfTypeDefineState_CETypeInit) && (type->WantsGCMarking())) typeFlags |= BfTypeFlags_WantsMarking; if ((typeInstance != NULL) && (typeInstance->mTypeDef->mIsStatic)) @@ -6189,6 +6144,115 @@ BfIRValue BfModule::CreateTypeData(BfType* type, BfCreateTypeDataContext& ctx, b if ((typeInstance != NULL) && (typeInstance->mTypeDef->mIsAbstract)) typeFlags |= BfTypeFlags_Abstract; + return typeTypeData; +} + +BfIRValue BfModule::CreateTypeDeclData(BfType* type) +{ + auto typeDeclType = ResolveTypeDef(mCompiler->mTypeTypeDeclDef)->ToTypeInstance(); + + int typeCode = 0; + int typeFlags = 0; + + BfCreateTypeDataContext createTypeDataCtx; + BfIRValue typeTypeData = GetTypeTypeData(type, createTypeDataCtx, true, true, true, typeFlags, typeCode); + + SizedArray typeValueParams; + GetConstClassValueParam(typeTypeData, typeValueParams); + + BfType* longType = GetPrimitiveType(BfTypeCode_Int64); + BfType* intType = GetPrimitiveType(BfTypeCode_Int32); + BfType* intPtrType = GetPrimitiveType(BfTypeCode_IntPtr); + BfType* shortType = GetPrimitiveType(BfTypeCode_Int16); + BfType* byteType = GetPrimitiveType(BfTypeCode_Int8); + + BfType* typeIdType = intType; + + auto typeInst = type->ToTypeInstance(); + + auto outerType = GetOuterType(type); + BfType* baseType = NULL; + if (typeInst != NULL) + baseType = typeInst->mBaseType; + + BfIRValue objectData = mBfIRBuilder->CreateConstAgg_Value(mBfIRBuilder->MapTypeInst(mContext->mBfObjectType, BfIRPopulateType_Full), typeValueParams); + SizedArray typeDataParams = + { + objectData, + GetConstValue(type->mTypeId, typeIdType), // mTypeId + GetConstValue((baseType != NULL) ? baseType->mTypeId : 0, typeIdType), // mBaseTypeId + GetConstValue((outerType != NULL) ? outerType->mTypeId : 0, typeIdType), // mOuterTypeId + GetConstValue(typeFlags, intType), // mTypeFlags + GetConstValue(typeCode, byteType), // mTypeCode + }; + FixConstValueParams(typeDeclType, typeDataParams); + auto typeData = mBfIRBuilder->CreateConstAgg_Value(mBfIRBuilder->MapTypeInst(typeDeclType, BfIRPopulateType_Full), typeDataParams); + + String typeDataName = StrFormat("sBfTypeDeclData.%d", type->mTypeId); + BfIRValue typeDataVar = mBfIRBuilder->CreateGlobalVariable(mBfIRBuilder->MapTypeInst(typeDeclType), true, + BfIRLinkageType_External, typeData, typeDataName); + mBfIRBuilder->GlobalVar_SetAlignment(typeDataVar, mSystem->mPtrSize); + + return typeDataVar; +} + +BfIRValue BfModule::CreateTypeData(BfType* type, BfCreateTypeDataContext& ctx, bool forceReflectFields, bool needsTypeData, bool needsTypeNames, bool needsVData) +{ + if ((IsHotCompile()) && (!type->mDirty)) + return BfIRValue(); + + BfIRValue* irValuePtr = NULL; + if (mTypeDataRefs.TryGetValue(type, &irValuePtr)) + { + return *irValuePtr; + } + + BfTypeInstance* typeInstance = type->ToTypeInstance(); + BfType* typeInstanceType = ResolveTypeDef(mCompiler->mReflectTypeInstanceTypeDef); + mBfIRBuilder->PopulateType(typeInstanceType, BfIRPopulateType_Full_ForceDefinition); + + if (typeInstanceType == NULL) + { + AssertErrorState(); + return BfIRValue(); + } + + int typeCode = BfTypeCode_None; + int typeFlags = 0; + BfIRValue typeTypeData = GetTypeTypeData(type, ctx, needsTypeData, false, needsTypeNames, typeFlags, typeCode); + + BfType* longType = GetPrimitiveType(BfTypeCode_Int64); + BfType* intType = GetPrimitiveType(BfTypeCode_Int32); + BfType* intPtrType = GetPrimitiveType(BfTypeCode_IntPtr); + BfType* shortType = GetPrimitiveType(BfTypeCode_Int16); + BfType* byteType = GetPrimitiveType(BfTypeCode_Int8); + + BfType* typeIdType = intType; + + auto voidPtrType = GetPrimitiveType(BfTypeCode_NullPtr); + auto voidPtrIRType = mBfIRBuilder->MapType(voidPtrType); + auto voidPtrPtrIRType = mBfIRBuilder->GetPointerTo(voidPtrIRType); + auto voidPtrNull = GetDefaultValue(voidPtrType); + + SizedArray typeValueParams; + GetConstClassValueParam(typeTypeData, typeValueParams); + + FixConstValueParams(mContext->mBfObjectType, typeValueParams); + BfIRValue objectData = mBfIRBuilder->CreateConstAgg_Value(mBfIRBuilder->MapTypeInst(mContext->mBfObjectType, BfIRPopulateType_Full), typeValueParams); + + StringT<512> typeDataName; + if ((typeInstance != NULL) && (!typeInstance->IsTypeAlias())) + { + BfMangler::MangleStaticFieldName(typeDataName, mCompiler->GetMangleKind(), typeInstance, "sBfTypeData"); + if (typeInstance->mTypeDef->IsGlobalsContainer()) + typeDataName += "`G`" + typeInstance->mTypeDef->mProject->mName; + } + else + { + typeDataName += "sBfTypeData."; + BfMangler::Mangle(typeDataName, mCompiler->GetMangleKind(), type, mContext->mScratchModule); + } + int virtSlotIdx = -1; if ((typeInstance != NULL) && (typeInstance->mSlotNum >= 0)) virtSlotIdx = typeInstance->mSlotNum + mCompiler->GetVDataPrefixDataCount() + mCompiler->GetDynCastVDataCount(); diff --git a/IDEHelper/Compiler/BfModule.h b/IDEHelper/Compiler/BfModule.h index e51ae059..4020bdcf 100644 --- a/IDEHelper/Compiler/BfModule.h +++ b/IDEHelper/Compiler/BfModule.h @@ -2093,6 +2093,8 @@ public: void EncodeAttributeData(BfTypeInstance* typeInstance, BfType* argType, BfIRValue arg, SizedArrayImpl& data, Dictionary& usedStringIdMap); BfIRValue CreateFieldData(BfFieldInstance* fieldInstance, int customAttrIdx); void CreateSlotOfs(BfTypeInstance* typeInstance); + BfIRValue GetTypeTypeData(BfType* type, BfCreateTypeDataContext& ctx, bool needsTypeData, bool wantsTypeDecl, bool needsTypeNames, int& typeFlags, int& typeCode); + BfIRValue CreateTypeDeclData(BfType* type); BfIRValue CreateTypeData(BfType* type, BfCreateTypeDataContext& ctx, bool forceReflectFields, bool needsTypeData, bool needsTypeNames, bool needsVData); BfIRValue FixClassVData(BfIRValue value); diff --git a/IDEHelper/Compiler/CeMachine.cpp b/IDEHelper/Compiler/CeMachine.cpp index e4115e93..27f51654 100644 --- a/IDEHelper/Compiler/CeMachine.cpp +++ b/IDEHelper/Compiler/CeMachine.cpp @@ -3878,6 +3878,53 @@ addr_ce CeContext::GetConstantData(BeConstant* constant) return (addr_ce)(ptr - mMemory.mVals); } + +addr_ce CeContext::GetReflectTypeDecl(int typeId) +{ + addr_ce* addrPtr = NULL; + if (!mReflectDeclMap.TryAdd(typeId, NULL, &addrPtr)) + return *addrPtr; + + auto ceModule = mCeMachine->mCeModule; + SetAndRestoreValue ignoreWrites(ceModule->mBfIRBuilder->mIgnoreWrites, false); + + if (ceModule->mContext->mBfTypeType == NULL) + ceModule->mContext->ReflectInit(); + + if ((uintptr)typeId >= (uintptr)mCeMachine->mCeModule->mContext->mTypes.mSize) + return 0; + auto bfType = mCeMachine->mCeModule->mContext->mTypes[typeId]; + if (bfType == NULL) + return 0; + + if (bfType->mDefineState < BfTypeDefineState_HasInterfaces_Direct) + ceModule->PopulateType(bfType, BfPopulateType_Interfaces_Direct); + + BfCreateTypeDataContext createTypeDataCtx; + auto irData = ceModule->CreateTypeDeclData(bfType); + + BeValue* beValue = NULL; + if (auto constant = mCeMachine->mCeModule->mBfIRBuilder->GetConstant(irData)) + { + if (constant->mConstType == BfConstType_BitCast) + { + auto bitcast = (BfConstantBitCast*)constant; + constant = mCeMachine->mCeModule->mBfIRBuilder->GetConstantById(bitcast->mTarget); + } + if (constant->mConstType == BfConstType_GlobalVar) + { + auto globalVar = (BfGlobalVar*)constant; + beValue = mCeMachine->mCeModule->mBfIRBuilder->mBeIRCodeGen->GetBeValue(globalVar->mStreamId); + } + } + + if (auto constant = BeValueDynCast(beValue)) + *addrPtr = GetConstantData(constant); + + // We need to 'get' again because we might have resized + return *addrPtr; +} + addr_ce CeContext::GetReflectType(int typeId) { addr_ce* addrPtr = NULL; @@ -3924,7 +3971,7 @@ addr_ce CeContext::GetReflectType(int typeId) return *addrPtr; } -addr_ce CeContext::GetReflectType(const String& typeName) +addr_ce CeContext::GetReflectType(const String& typeName, bool useDeclaration) { if (mCeMachine->mTempParser == NULL) { @@ -3964,7 +4011,7 @@ addr_ce CeContext::GetReflectType(const String& typeName) if (type == NULL) return 0; - return GetReflectType(type->mTypeId); + return useDeclaration ? GetReflectTypeDecl(type->mTypeId) : GetReflectType(type->mTypeId); } int CeContext::GetTypeIdFromType(addr_ce typeAddr) @@ -6036,6 +6083,110 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* OutputDebugStrF("Debug Val: %lld %llX\n", intVal, intVal); } } + else if (checkFunction->mFunctionKind == CeFunctionKind_GetReflectTypeDeclById) + { + int32 typeId = *(int32*)((uint8*)stackPtr + ceModule->mSystem->mPtrSize); + auto reflectType = GetReflectTypeDecl(typeId); + _FixVariables(); + CeSetAddrVal(stackPtr + 0, reflectType, ptrSize); + } + else if (checkFunction->mFunctionKind == CeFunctionKind_GetReflectTypeDeclByName) + { + addr_ce strViewPtr = *(addr_ce*)((uint8*)stackPtr + ptrSize); + String typeName; + if (!GetStringFromStringView(strViewPtr, typeName)) + { + _Fail("Invalid StringView"); + return false; + } + auto reflectType = GetReflectType(typeName, true); + _FixVariables(); + CeSetAddrVal(stackPtr + 0, reflectType, ptrSize); + } + else if (checkFunction->mFunctionKind == CeFunctionKind_GetReflectNextTypeDecl) + { + int32 typeId = *(int32*)((uint8*)stackPtr + ceModule->mSystem->mPtrSize); + + addr_ce reflectType = 0; + + auto context = mCeMachine->mCeModule->mContext; + while (true) + { + typeId++; + if (typeId >= mCeMachine->mCeModule->mContext->mTypes.mSize) + break; + auto bfType = mCeMachine->mCeModule->mContext->mTypes[typeId]; + if (bfType != NULL) + { + if (bfType->IsOnDemand()) + continue; + if (bfType->IsBoxed()) + continue; + if (bfType->IsArray()) + continue; + if (bfType->IsNullable()) + continue; + + auto bfTypeInst = bfType->ToTypeInstance(); + if (bfTypeInst == NULL) + continue; + + if (bfTypeInst->mTypeDef->mTypeDeclaration == NULL) + continue; + + if (bfTypeInst->IsGenericTypeInstance()) + { + if (!bfTypeInst->IsUnspecializedType()) + continue; + if (bfTypeInst->IsUnspecializedTypeVariation()) + continue; + } + + auto curProject = mCurModule->mProject; + auto declProject = bfTypeInst->mTypeDef->mProject; + + if ((declProject != curProject) && (!curProject->HasDependency(declProject))) + continue; + + reflectType = GetReflectTypeDecl(typeId); + if (reflectType != 0) + break; + } + } + + _FixVariables(); + CeSetAddrVal(stackPtr + 0, reflectType, ptrSize); + } + else if (checkFunction->mFunctionKind == CeFunctionKind_HasDeclaredMember) + { + int32 typeId = *(int32*)((uint8*)stackPtr + 1); + int32 memberKind = *(int32*)((uint8*)stackPtr + 1 + 4); + addr_ce strViewPtr = *(addr_ce*)((uint8*)stackPtr + 1 + 4 + 4); + + bool hasMember; + + String typeName; + if (!GetStringFromStringView(strViewPtr, typeName)) + { + _Fail("Invalid StringView"); + return false; + } + + BfType* type = GetBfType(typeId); + if ((type != NULL) && (type->IsTypeInstance())) + { + auto typeInst = type->ToTypeInstance(); + typeInst->mTypeDef->PopulateMemberSets(); + if (memberKind == 0) // Field + hasMember = typeInst->mTypeDef->mFieldSet.ContainsWith((StringImpl&)typeName); + else if (memberKind == 1) // Method + hasMember = typeInst->mTypeDef->mMethodSet.ContainsWith((StringImpl&)typeName); + else if (memberKind == 2) // Property + hasMember = typeInst->mTypeDef->mPropertySet.ContainsWith((StringImpl&)typeName); + } + + *(addr_ce*)(stackPtr + 0) = hasMember; + } else if (checkFunction->mFunctionKind == CeFunctionKind_GetReflectType) { addr_ce objAddr = *(addr_ce*)((uint8*)stackPtr + ceModule->mSystem->mPtrSize); @@ -6062,7 +6213,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* _Fail("Invalid StringView"); return false; } - auto reflectType = GetReflectType(typeName); + auto reflectType = GetReflectType(typeName, false); _FixVariables(); CeSetAddrVal(stackPtr + 0, reflectType, ptrSize); } @@ -6089,9 +6240,54 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* SetAndRestoreValue prevMethodInstance(mCeMachine->mCeModule->mCurMethodInstance, mCallerMethodInstance); SetAndRestoreValue prevTypeInstance(mCeMachine->mCeModule->mCurTypeInstance, mCallerTypeInstance); - CeSetAddrVal(stackPtr + 0, GetString(mCeMachine->mCeModule->TypeToString(type)), ptrSize); + + String typeName; + mCeMachine->mCeModule->DoTypeToString(typeName, type, BfTypeNameFlags_None); + CeSetAddrVal(stackPtr + 0, GetString(typeName), ptrSize); _FixVariables(); } + else if (checkFunction->mFunctionKind == CeFunctionKind_TypeName_ToString) + { + int32 typeId = *(int32*)((uint8*)stackPtr + ptrSize); + + BfType* type = GetBfType(typeId); + bool success = false; + if (type == NULL) + { + _Fail("Invalid type"); + return false; + } + + String str; + if (auto typeInst = type->ToTypeInstance()) + str = typeInst->mTypeDef->mName->ToString(); + + SetAndRestoreValue prevMethodInstance(mCeMachine->mCeModule->mCurMethodInstance, mCallerMethodInstance); + SetAndRestoreValue prevTypeInstance(mCeMachine->mCeModule->mCurTypeInstance, mCallerTypeInstance); + CeSetAddrVal(stackPtr + 0, GetString(str), ptrSize); + _FixVariables(); + } + else if (checkFunction->mFunctionKind == CeFunctionKind_Namespace_ToString) + { + int32 typeId = *(int32*)((uint8*)stackPtr + ptrSize); + + BfType* type = GetBfType(typeId); + bool success = false; + if (type == NULL) + { + _Fail("Invalid type"); + return false; + } + + String str; + if (auto typeInst = type->ToTypeInstance()) + typeInst->mTypeDef->mNamespace.ToString(str); + + SetAndRestoreValue prevMethodInstance(mCeMachine->mCeModule->mCurMethodInstance, mCallerMethodInstance); + SetAndRestoreValue prevTypeInstance(mCeMachine->mCeModule->mCurTypeInstance, mCallerTypeInstance); + CeSetAddrVal(stackPtr + 0, GetString(str), ptrSize); + _FixVariables(); + } else if (checkFunction->mFunctionKind == CeFunctionKind_Type_GetCustomAttribute) { int32 typeId = *(int32*)((uint8*)stackPtr + 1); @@ -9650,7 +9846,23 @@ void CeMachine::CheckFunctionKind(CeFunction* ceFunction) } else if (owner->IsInstanceOf(mCeModule->mCompiler->mTypeTypeDef)) { - if (methodDef->mName == "Comptime_GetTypeById") + if (methodDef->mName == "Comptime_GetTypeDeclarationById") + { + ceFunction->mFunctionKind = CeFunctionKind_GetReflectTypeDeclById; + } + if (methodDef->mName == "Comptime_GetTypeDeclarationByName") + { + ceFunction->mFunctionKind = CeFunctionKind_GetReflectTypeDeclByName; + } + else if (methodDef->mName == "Comptime_GetNextTypeDeclaration") + { + ceFunction->mFunctionKind = CeFunctionKind_GetReflectNextTypeDecl; + } + else if (methodDef->mName == "Comptime_Type_HasDeclaredMember") + { + ceFunction->mFunctionKind = CeFunctionKind_HasDeclaredMember; + } + else if (methodDef->mName == "Comptime_GetTypeById") { ceFunction->mFunctionKind = CeFunctionKind_GetReflectTypeById; } @@ -9666,6 +9878,14 @@ void CeMachine::CheckFunctionKind(CeFunction* ceFunction) { ceFunction->mFunctionKind = CeFunctionKind_Type_ToString; } + else if (methodDef->mName == "Comptime_TypeName_ToString") + { + ceFunction->mFunctionKind = CeFunctionKind_TypeName_ToString; + } + else if (methodDef->mName == "Comptime_Namespace_ToString") + { + ceFunction->mFunctionKind = CeFunctionKind_Namespace_ToString; + } else if (methodDef->mName == "Comptime_Type_GetCustomAttribute") { ceFunction->mFunctionKind = CeFunctionKind_Type_GetCustomAttribute; @@ -10259,7 +10479,8 @@ CeContext* CeMachine::AllocContext() void CeMachine::ReleaseContext(CeContext* ceContext) { ceContext->mStringMap.Clear(); - ceContext->mReflectMap.Clear(); + ceContext->mReflectDeclMap.Clear(); + ceContext->mReflectMap.Clear(); ceContext->mConstDataMap.Clear(); ceContext->mMemory.Clear(); if (ceContext->mMemory.mAllocSize > BF_CE_MAX_CARRYOVER_MEMORY) diff --git a/IDEHelper/Compiler/CeMachine.h b/IDEHelper/Compiler/CeMachine.h index 79bda5af..25f80b65 100644 --- a/IDEHelper/Compiler/CeMachine.h +++ b/IDEHelper/Compiler/CeMachine.h @@ -428,12 +428,18 @@ enum CeFunctionKind CeFunctionKind_DynCheckFailed, CeFunctionKind_FatalError, CeFunctionKind_DebugWrite, - CeFunctionKind_DebugWrite_Int, + CeFunctionKind_DebugWrite_Int, + CeFunctionKind_GetReflectTypeDeclById, + CeFunctionKind_GetReflectTypeDeclByName, + CeFunctionKind_GetReflectNextTypeDecl, + CeFunctionKind_HasDeclaredMember, CeFunctionKind_GetReflectType, CeFunctionKind_GetReflectTypeById, CeFunctionKind_GetReflectTypeByName, CeFunctionKind_GetReflectSpecializedType, CeFunctionKind_Type_ToString, + CeFunctionKind_TypeName_ToString, + CeFunctionKind_Namespace_ToString, CeFunctionKind_Type_GetCustomAttribute, CeFunctionKind_Field_GetCustomAttribute, CeFunctionKind_Method_GetCustomAttribute, @@ -1105,6 +1111,7 @@ public: int mStackSize; Dictionary mStringMap; Dictionary mReflectMap; + Dictionary mReflectDeclMap; Dictionary mConstDataMap; HashSet mStaticCtorExecSet; Dictionary mStaticFieldMap; @@ -1137,8 +1144,9 @@ public: uint8* CeMalloc(int size); bool CeFree(addr_ce addr); addr_ce CeAllocArray(BfArrayType* arrayType, int count, addr_ce& elemsAddr); + addr_ce GetReflectTypeDecl(int typeId); addr_ce GetReflectType(int typeId); - addr_ce GetReflectType(const String& typeName); + addr_ce GetReflectType(const String& typeName, bool useDeclaration); int GetTypeIdFromType(addr_ce typeAddr); addr_ce GetReflectSpecializedType(addr_ce unspecializedType, addr_ce typeArgsSpanAddr); addr_ce GetString(int stringId);