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:
parent
89651c4a76
commit
e30972d3af
10 changed files with 753 additions and 250 deletions
|
@ -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);
|
||||
|
|
|
@ -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('>');
|
||||
}
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -376,6 +376,7 @@ public:
|
|||
BfTypeDef* mEnumTypeDef;
|
||||
BfTypeDef* mStringTypeDef;
|
||||
BfTypeDef* mStringViewTypeDef;
|
||||
BfTypeDef* mTypeTypeDeclDef;
|
||||
BfTypeDef* mTypeTypeDef;
|
||||
BfTypeDef* mValueTypeTypeDef;
|
||||
BfTypeDef* mResultTypeDef;
|
||||
|
|
|
@ -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))
|
||||
{
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue