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

Added reflected TypeDeclaration support for comptime

This commit is contained in:
Brian Fiete 2025-01-14 10:16:46 -08:00
parent 89651c4a76
commit e30972d3af
10 changed files with 753 additions and 250 deletions

View file

@ -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<Object> args)
public static void Write(StringView fmt, params Span<Object> 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<Object> args)
{
String paramStr = scope String(4096);
paramStr.AppendF(strFormat, params args);

View file

@ -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<T>() 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<T> GetCustomAttribute<T>() 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<TypeDeclaration>
{
int32 mCurId;
public Result<TypeDeclaration> 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<TypeDeclaration> 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<Type> 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('>');
}

View file

@ -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
{

View file

@ -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");

View file

@ -376,6 +376,7 @@ public:
BfTypeDef* mEnumTypeDef;
BfTypeDef* mStringTypeDef;
BfTypeDef* mStringViewTypeDef;
BfTypeDef* mTypeTypeDeclDef;
BfTypeDef* mTypeTypeDef;
BfTypeDef* mValueTypeTypeDef;
BfTypeDef* mResultTypeDef;

View file

@ -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))
{

View file

@ -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<BfIRValue, 4> 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<BfIRValue, 4> 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<BfIRValue, 9> 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<BfIRValue, 4> 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();

View file

@ -2093,6 +2093,8 @@ public:
void EncodeAttributeData(BfTypeInstance* typeInstance, BfType* argType, BfIRValue arg, SizedArrayImpl<uint8>& data, Dictionary<int, int>& 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);

View file

@ -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<bool> 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<BeConstant>(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<BfMethodInstance*> prevMethodInstance(mCeMachine->mCeModule->mCurMethodInstance, mCallerMethodInstance);
SetAndRestoreValue<BfTypeInstance*> 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<BfMethodInstance*> prevMethodInstance(mCeMachine->mCeModule->mCurMethodInstance, mCallerMethodInstance);
SetAndRestoreValue<BfTypeInstance*> 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<BfMethodInstance*> prevMethodInstance(mCeMachine->mCeModule->mCurMethodInstance, mCallerMethodInstance);
SetAndRestoreValue<BfTypeInstance*> 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)

View file

@ -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<int, addr_ce> mStringMap;
Dictionary<int, addr_ce> mReflectMap;
Dictionary<int, addr_ce> mReflectDeclMap;
Dictionary<Val128, addr_ce> mConstDataMap;
HashSet<int> mStaticCtorExecSet;
Dictionary<String, CeStaticFieldInfo> 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);