mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-09 03:52:19 +02:00
Boxed struct ptr changes.
This commit is contained in:
parent
ad2542eba6
commit
5af6428bf4
20 changed files with 573 additions and 327 deletions
|
@ -1,12 +1,29 @@
|
||||||
namespace System
|
namespace System
|
||||||
{
|
{
|
||||||
struct Pointer
|
[AlwaysInclude]
|
||||||
|
struct Pointer : IHashable
|
||||||
{
|
{
|
||||||
|
void* mVal;
|
||||||
|
|
||||||
|
public int GetHashCode()
|
||||||
|
{
|
||||||
|
return (int)mVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Pointer<T>
|
[AlwaysInclude]
|
||||||
|
Object GetBoxed()
|
||||||
|
{
|
||||||
|
return new box this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Pointer<T> : IHashable
|
||||||
{
|
{
|
||||||
T* mVal;
|
T* mVal;
|
||||||
|
|
||||||
|
public int GetHashCode()
|
||||||
|
{
|
||||||
|
return (int)mVal;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -154,6 +154,14 @@ namespace System.Reflection
|
||||||
Type underlyingType = argType.UnderlyingType;
|
Type underlyingType = argType.UnderlyingType;
|
||||||
if ((paramType.IsPrimitive) && (underlyingType.IsTypedPrimitive)) // Boxed primitive?
|
if ((paramType.IsPrimitive) && (underlyingType.IsTypedPrimitive)) // Boxed primitive?
|
||||||
underlyingType = underlyingType.UnderlyingType;
|
underlyingType = underlyingType.UnderlyingType;
|
||||||
|
|
||||||
|
if (argType.IsBoxedStructPtr)
|
||||||
|
{
|
||||||
|
dataPtr = *(void**)dataPtr;
|
||||||
|
handled = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
if (!underlyingType.IsSubtypeOf(paramType))
|
if (!underlyingType.IsSubtypeOf(paramType))
|
||||||
{
|
{
|
||||||
if (underlyingType.IsGenericType)
|
if (underlyingType.IsGenericType)
|
||||||
|
@ -175,6 +183,7 @@ namespace System.Reflection
|
||||||
|
|
||||||
}*/
|
}*/
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!handled)
|
if (!handled)
|
||||||
{
|
{
|
||||||
|
|
|
@ -213,6 +213,14 @@ namespace System
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool IsPointer
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return (mTypeFlags & (TypeFlags.Boxed | TypeFlags.Pointer)) == TypeFlags.Pointer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public bool IsBoxed
|
public bool IsBoxed
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
|
@ -221,6 +229,14 @@ namespace System
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool IsBoxedStructPtr
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return (mTypeFlags & (TypeFlags.Boxed | TypeFlags.Pointer)) == TypeFlags.Boxed | TypeFlags.Pointer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public bool IsEnum
|
public bool IsEnum
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
|
|
|
@ -1358,12 +1358,11 @@ void BeIRCodeGen::HandleNextCmd()
|
||||||
CMD_PARAM(BeValue*, val);
|
CMD_PARAM(BeValue*, val);
|
||||||
CMD_PARAM(int, idx);
|
CMD_PARAM(int, idx);
|
||||||
|
|
||||||
|
BF_ASSERT(val->GetType()->IsComposite());
|
||||||
|
|
||||||
auto extractValueInst = mBeModule->AllocInst<BeExtractValueInst>();
|
auto extractValueInst = mBeModule->AllocInst<BeExtractValueInst>();
|
||||||
extractValueInst->mAggVal = val;
|
extractValueInst->mAggVal = val;
|
||||||
extractValueInst->mIdx = idx;
|
extractValueInst->mIdx = idx;
|
||||||
|
|
||||||
BF_ASSERT(val->GetType()->IsComposite());
|
|
||||||
|
|
||||||
SetResult(curId, extractValueInst);
|
SetResult(curId, extractValueInst);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -2394,6 +2394,20 @@ void BeModule::Print(BeFunction* func)
|
||||||
OutputDebugStr(ToString(func));
|
OutputDebugStr(ToString(func));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BeModule::PrintValue(BeValue* val)
|
||||||
|
{
|
||||||
|
BeDumpContext dumpCtx;
|
||||||
|
dumpCtx.mModule = this;
|
||||||
|
String str;
|
||||||
|
dumpCtx.ToString(str, val);
|
||||||
|
str += "\n";
|
||||||
|
OutputDebugStr(str);
|
||||||
|
|
||||||
|
auto type = val->GetType();
|
||||||
|
if (type != NULL)
|
||||||
|
bpt(type);
|
||||||
|
}
|
||||||
|
|
||||||
void BeModule::DoInlining(BeFunction* func)
|
void BeModule::DoInlining(BeFunction* func)
|
||||||
{
|
{
|
||||||
//bool debugging = func->mName == "?Test@Program@bf@@CAXXZ";
|
//bool debugging = func->mName == "?Test@Program@bf@@CAXXZ";
|
||||||
|
@ -3139,8 +3153,8 @@ BeGEPInst* BeModule::CreateGEP(BeValue* ptr, BeValue* idx0, BeValue* idx1)
|
||||||
inst->mIdx1 = idx1;
|
inst->mIdx1 = idx1;
|
||||||
AddInst(inst);
|
AddInst(inst);
|
||||||
|
|
||||||
BF_ASSERT(ptr->GetType()->IsPointer());
|
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
|
BF_ASSERT(ptr->GetType()->IsPointer());
|
||||||
inst->GetType();
|
inst->GetType();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -2109,6 +2109,7 @@ public:
|
||||||
String ToString(BeFunction* func = NULL);
|
String ToString(BeFunction* func = NULL);
|
||||||
void Print();
|
void Print();
|
||||||
void Print(BeFunction* func);
|
void Print(BeFunction* func);
|
||||||
|
void PrintValue(BeValue* val);
|
||||||
|
|
||||||
void DoInlining(BeFunction* func);
|
void DoInlining(BeFunction* func);
|
||||||
void DoInlining();
|
void DoInlining();
|
||||||
|
|
|
@ -2427,12 +2427,6 @@ public:
|
||||||
BfTokenNode* mRefToken;
|
BfTokenNode* mRefToken;
|
||||||
}; BF_AST_DECL(BfRefTypeRef, BfElementedTypeRef);
|
}; BF_AST_DECL(BfRefTypeRef, BfElementedTypeRef);
|
||||||
|
|
||||||
class BfBoxedTypeRef : public BfElementedTypeRef
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
BF_AST_TYPE(BfBoxedTypeRef, BfElementedTypeRef);
|
|
||||||
}; BF_AST_DECL(BfBoxedTypeRef, BfElementedTypeRef);
|
|
||||||
|
|
||||||
class BfParamsExpression : public BfExpression
|
class BfParamsExpression : public BfExpression
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -1394,7 +1394,7 @@ void BfAutoComplete::CheckIdentifier(BfIdentifierNode* identifierNode, bool isIn
|
||||||
"delegate", "extern", "enum", "explicit", "extension", "function",
|
"delegate", "extern", "enum", "explicit", "extension", "function",
|
||||||
"interface", "in", "internal", "mixin", "namespace", "new",
|
"interface", "in", "internal", "mixin", "namespace", "new",
|
||||||
"operator", "out", "override", "params", "private", "protected", "public", "readonly", "ref", "rettype", "return",
|
"operator", "out", "override", "params", "private", "protected", "public", "readonly", "ref", "rettype", "return",
|
||||||
"sealed", "static", "struct", "this", "typealias",
|
"scope", "sealed", "static", "struct", "this", "typealias",
|
||||||
"using", "virtual", "volatile", "T", "where"
|
"using", "virtual", "volatile", "T", "where"
|
||||||
};
|
};
|
||||||
for (int i = 0; i < sizeof(tokens)/sizeof(char*); i++)
|
for (int i = 0; i < sizeof(tokens)/sizeof(char*); i++)
|
||||||
|
|
|
@ -397,6 +397,7 @@ BfCompiler::BfCompiler(BfSystem* bfSystem, bool isResolveOnly)
|
||||||
mInlineAttributeTypeDef = NULL;
|
mInlineAttributeTypeDef = NULL;
|
||||||
mInternalTypeDef = NULL;
|
mInternalTypeDef = NULL;
|
||||||
mIPrintableTypeDef = NULL;
|
mIPrintableTypeDef = NULL;
|
||||||
|
mIHashableTypeDef = NULL;
|
||||||
mLinkNameAttributeTypeDef = NULL;
|
mLinkNameAttributeTypeDef = NULL;
|
||||||
mMethodRefTypeDef = NULL;
|
mMethodRefTypeDef = NULL;
|
||||||
mNullableTypeDef = NULL;
|
mNullableTypeDef = NULL;
|
||||||
|
@ -422,6 +423,9 @@ BfCompiler::BfCompiler(BfSystem* bfSystem, bool isResolveOnly)
|
||||||
mTypeTypeDef = NULL;
|
mTypeTypeDef = NULL;
|
||||||
mUnboundAttributeTypeDef = NULL;
|
mUnboundAttributeTypeDef = NULL;
|
||||||
mValueTypeTypeDef = NULL;
|
mValueTypeTypeDef = NULL;
|
||||||
|
mObsoleteAttributeTypeDef = NULL;
|
||||||
|
mErrorAttributeTypeDef = NULL;
|
||||||
|
mWarnAttributeTypeDef = NULL;
|
||||||
|
|
||||||
mLastAutocompleteModule = NULL;
|
mLastAutocompleteModule = NULL;
|
||||||
}
|
}
|
||||||
|
@ -4826,6 +4830,9 @@ void BfCompiler::PopulateReified()
|
||||||
|
|
||||||
void BfCompiler::HotCommit()
|
void BfCompiler::HotCommit()
|
||||||
{
|
{
|
||||||
|
if (mHotState == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
mHotState->mCommittedHotCompileIdx = mOptions.mHotCompileIdx;
|
mHotState->mCommittedHotCompileIdx = mOptions.mHotCompileIdx;
|
||||||
|
|
||||||
for (auto type : mContext->mResolvedTypes)
|
for (auto type : mContext->mResolvedTypes)
|
||||||
|
@ -5808,6 +5815,7 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory)
|
||||||
mInlineAttributeTypeDef = _GetRequiredType("System.InlineAttribute");
|
mInlineAttributeTypeDef = _GetRequiredType("System.InlineAttribute");
|
||||||
mInternalTypeDef = _GetRequiredType("System.Internal");
|
mInternalTypeDef = _GetRequiredType("System.Internal");
|
||||||
mIPrintableTypeDef = _GetRequiredType("System.IPrintable");
|
mIPrintableTypeDef = _GetRequiredType("System.IPrintable");
|
||||||
|
mIHashableTypeDef = _GetRequiredType("System.IHashable");
|
||||||
mLinkNameAttributeTypeDef = _GetRequiredType("System.LinkNameAttribute");
|
mLinkNameAttributeTypeDef = _GetRequiredType("System.LinkNameAttribute");
|
||||||
mMethodRefTypeDef = _GetRequiredType("System.MethodReference", 1);
|
mMethodRefTypeDef = _GetRequiredType("System.MethodReference", 1);
|
||||||
mNullableTypeDef = _GetRequiredType("System.Nullable");
|
mNullableTypeDef = _GetRequiredType("System.Nullable");
|
||||||
|
@ -5834,6 +5842,9 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory)
|
||||||
mTypeTypeDef = _GetRequiredType("System.Type");
|
mTypeTypeDef = _GetRequiredType("System.Type");
|
||||||
mUnboundAttributeTypeDef = _GetRequiredType("System.UnboundAttribute");
|
mUnboundAttributeTypeDef = _GetRequiredType("System.UnboundAttribute");
|
||||||
mValueTypeTypeDef = _GetRequiredType("System.ValueType");
|
mValueTypeTypeDef = _GetRequiredType("System.ValueType");
|
||||||
|
mObsoleteAttributeTypeDef = _GetRequiredType("System.ObsoleteAttribute");
|
||||||
|
mErrorAttributeTypeDef = _GetRequiredType("System.ErrorAttribute");
|
||||||
|
mWarnAttributeTypeDef = _GetRequiredType("System.WarnAttribute");
|
||||||
|
|
||||||
for (int i = 0; i < BfTypeCode_Length; i++)
|
for (int i = 0; i < BfTypeCode_Length; i++)
|
||||||
mContext->mPrimitiveStructTypes[i] = NULL;
|
mContext->mPrimitiveStructTypes[i] = NULL;
|
||||||
|
|
|
@ -325,33 +325,30 @@ public:
|
||||||
BfTypeDef* mArray3TypeDef;
|
BfTypeDef* mArray3TypeDef;
|
||||||
BfTypeDef* mArray4TypeDef;
|
BfTypeDef* mArray4TypeDef;
|
||||||
BfTypeDef* mSpanTypeDef;
|
BfTypeDef* mSpanTypeDef;
|
||||||
BfTypeDef* mAttributeTypeDef;
|
|
||||||
BfTypeDef* mAttributeUsageAttributeTypeDef;
|
|
||||||
BfTypeDef* mBfObjectTypeDef;
|
BfTypeDef* mBfObjectTypeDef;
|
||||||
BfTypeDef* mClassVDataTypeDef;
|
BfTypeDef* mClassVDataTypeDef;
|
||||||
BfTypeDef* mCLinkAttributeTypeDef;
|
|
||||||
BfTypeDef* mCReprAttributeTypeDef;
|
|
||||||
BfTypeDef* mNoDiscardAttributeTypeDef;
|
|
||||||
BfTypeDef* mDisableObjectAccessChecksAttributeTypeDef;
|
|
||||||
BfTypeDef* mDbgRawAllocDataTypeDef;
|
BfTypeDef* mDbgRawAllocDataTypeDef;
|
||||||
BfTypeDef* mDeferredCallTypeDef;
|
BfTypeDef* mDeferredCallTypeDef;
|
||||||
BfTypeDef* mDelegateTypeDef;
|
BfTypeDef* mDelegateTypeDef;
|
||||||
BfTypeDef* mEnumTypeDef;
|
BfTypeDef* mEnumTypeDef;
|
||||||
BfTypeDef* mFriendAttributeTypeDef;
|
BfTypeDef* mStringTypeDef;
|
||||||
BfTypeDef* mCheckedAttributeTypeDef;
|
BfTypeDef* mTypeTypeDef;
|
||||||
BfTypeDef* mUncheckedAttributeTypeDef;
|
BfTypeDef* mValueTypeTypeDef;
|
||||||
BfTypeDef* mFunctionTypeDef;
|
BfTypeDef* mFunctionTypeDef;
|
||||||
BfTypeDef* mGCTypeDef;
|
BfTypeDef* mGCTypeDef;
|
||||||
BfTypeDef* mGenericIEnumerableTypeDef;
|
BfTypeDef* mGenericIEnumerableTypeDef;
|
||||||
BfTypeDef* mGenericIEnumeratorTypeDef;
|
BfTypeDef* mGenericIEnumeratorTypeDef;
|
||||||
BfTypeDef* mGenericIRefEnumeratorTypeDef;
|
BfTypeDef* mGenericIRefEnumeratorTypeDef;
|
||||||
BfTypeDef* mInlineAttributeTypeDef;
|
|
||||||
BfTypeDef* mInternalTypeDef;
|
BfTypeDef* mInternalTypeDef;
|
||||||
BfTypeDef* mIPrintableTypeDef;
|
BfTypeDef* mIPrintableTypeDef;
|
||||||
BfTypeDef* mLinkNameAttributeTypeDef;
|
BfTypeDef* mIHashableTypeDef;
|
||||||
|
|
||||||
BfTypeDef* mMethodRefTypeDef;
|
BfTypeDef* mMethodRefTypeDef;
|
||||||
BfTypeDef* mNullableTypeDef;
|
BfTypeDef* mNullableTypeDef;
|
||||||
BfTypeDef* mOrderedAttributeTypeDef;
|
|
||||||
BfTypeDef* mPointerTTypeDef;
|
BfTypeDef* mPointerTTypeDef;
|
||||||
BfTypeDef* mPointerTypeDef;
|
BfTypeDef* mPointerTypeDef;
|
||||||
BfTypeDef* mReflectArrayType;
|
BfTypeDef* mReflectArrayType;
|
||||||
|
@ -364,16 +361,30 @@ public:
|
||||||
BfTypeDef* mReflectSpecializedGenericType;
|
BfTypeDef* mReflectSpecializedGenericType;
|
||||||
BfTypeDef* mReflectTypeInstanceTypeDef;
|
BfTypeDef* mReflectTypeInstanceTypeDef;
|
||||||
BfTypeDef* mReflectUnspecializedGenericType;
|
BfTypeDef* mReflectUnspecializedGenericType;
|
||||||
|
|
||||||
BfTypeDef* mSizedArrayTypeDef;
|
BfTypeDef* mSizedArrayTypeDef;
|
||||||
|
BfTypeDef* mAttributeTypeDef;
|
||||||
|
BfTypeDef* mAttributeUsageAttributeTypeDef;
|
||||||
|
BfTypeDef* mLinkNameAttributeTypeDef;
|
||||||
|
BfTypeDef* mOrderedAttributeTypeDef;
|
||||||
|
BfTypeDef* mInlineAttributeTypeDef;
|
||||||
|
BfTypeDef* mCLinkAttributeTypeDef;
|
||||||
|
BfTypeDef* mCReprAttributeTypeDef;
|
||||||
|
BfTypeDef* mNoDiscardAttributeTypeDef;
|
||||||
|
BfTypeDef* mDisableObjectAccessChecksAttributeTypeDef;
|
||||||
|
BfTypeDef* mFriendAttributeTypeDef;
|
||||||
|
BfTypeDef* mCheckedAttributeTypeDef;
|
||||||
|
BfTypeDef* mUncheckedAttributeTypeDef;
|
||||||
BfTypeDef* mSkipAccessCheckAttributeTypeDef;
|
BfTypeDef* mSkipAccessCheckAttributeTypeDef;
|
||||||
BfTypeDef* mStaticInitAfterAttributeTypeDef;
|
BfTypeDef* mStaticInitAfterAttributeTypeDef;
|
||||||
BfTypeDef* mStaticInitPriorityAttributeTypeDef;
|
BfTypeDef* mStaticInitPriorityAttributeTypeDef;
|
||||||
BfTypeDef* mStringTypeDef;
|
|
||||||
BfTypeDef* mTestAttributeTypeDef;
|
BfTypeDef* mTestAttributeTypeDef;
|
||||||
BfTypeDef* mThreadStaticAttributeTypeDef;
|
BfTypeDef* mThreadStaticAttributeTypeDef;
|
||||||
BfTypeDef* mTypeTypeDef;
|
|
||||||
BfTypeDef* mUnboundAttributeTypeDef;
|
BfTypeDef* mUnboundAttributeTypeDef;
|
||||||
BfTypeDef* mValueTypeTypeDef;
|
BfTypeDef* mObsoleteAttributeTypeDef;
|
||||||
|
BfTypeDef* mErrorAttributeTypeDef;
|
||||||
|
BfTypeDef* mWarnAttributeTypeDef;
|
||||||
|
|
||||||
|
|
||||||
int mCurTypeId;
|
int mCurTypeId;
|
||||||
int mTypeInitCount;
|
int mTypeInitCount;
|
||||||
|
|
|
@ -88,6 +88,7 @@ BfContext::~BfContext()
|
||||||
int numTypesDeleted = 0;
|
int numTypesDeleted = 0;
|
||||||
for (auto type : mResolvedTypes)
|
for (auto type : mResolvedTypes)
|
||||||
{
|
{
|
||||||
|
//_CrtCheckMemory();
|
||||||
delete type;
|
delete type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -930,6 +931,11 @@ void BfContext::RebuildType(BfType* type, bool deleteOnDemandTypes, bool rebuild
|
||||||
typeInst->mIsSplattable = false;
|
typeInst->mIsSplattable = false;
|
||||||
typeInst->mHasPackingHoles = false;
|
typeInst->mHasPackingHoles = false;
|
||||||
typeInst->mWantsGCMarking = false;
|
typeInst->mWantsGCMarking = false;
|
||||||
|
if (typeInst->mTypeInfoEx != NULL)
|
||||||
|
{
|
||||||
|
delete typeInst->mTypeInfoEx;
|
||||||
|
typeInst->mTypeInfoEx = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (typeInst->IsGenericTypeInstance())
|
if (typeInst->IsGenericTypeInstance())
|
||||||
{
|
{
|
||||||
|
@ -2082,6 +2088,9 @@ void BfContext::GenerateModuleName_Type(BfType* type, String& name)
|
||||||
if (type->IsBoxed())
|
if (type->IsBoxed())
|
||||||
{
|
{
|
||||||
auto boxedType = (BfBoxedType*)type;
|
auto boxedType = (BfBoxedType*)type;
|
||||||
|
if (boxedType->IsBoxedStructPtr())
|
||||||
|
name += "BOXPTR_";
|
||||||
|
else
|
||||||
name += "BOX_";
|
name += "BOX_";
|
||||||
GenerateModuleName_Type(boxedType->mElementType, name);
|
GenerateModuleName_Type(boxedType->mElementType, name);
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -1730,6 +1730,8 @@ String BfIRBuilder::GetDebugTypeName(BfTypeInstance* typeInstance, bool includeO
|
||||||
{
|
{
|
||||||
BfBoxedType* boxedType = (BfBoxedType*)typeInstance;
|
BfBoxedType* boxedType = (BfBoxedType*)typeInstance;
|
||||||
typeName = mModule->TypeToString(boxedType->mElementType, (BfTypeNameFlags)(BfTypeNameFlag_ResolveGenericParamNames | BfTypeNameFlag_AddGlobalContainerName));
|
typeName = mModule->TypeToString(boxedType->mElementType, (BfTypeNameFlags)(BfTypeNameFlag_ResolveGenericParamNames | BfTypeNameFlag_AddGlobalContainerName));
|
||||||
|
if (boxedType->IsBoxedStructPtr())
|
||||||
|
typeName += "*";
|
||||||
typeName = "Box<" + typeName + ">";
|
typeName = "Box<" + typeName + ">";
|
||||||
}
|
}
|
||||||
else if (includeOuterTypeName)
|
else if (includeOuterTypeName)
|
||||||
|
@ -2547,7 +2549,7 @@ void BfIRBuilder::CreateDbgTypeDefinition(BfType* type)
|
||||||
}
|
}
|
||||||
else if (type->IsBoxed())
|
else if (type->IsBoxed())
|
||||||
{
|
{
|
||||||
auto underlyingType = typeInstance->GetUnderlyingType();
|
auto underlyingType = ((BfBoxedType*)type)->GetModifiedElementType();
|
||||||
if (!underlyingType->IsValuelessType())
|
if (!underlyingType->IsValuelessType())
|
||||||
{
|
{
|
||||||
auto fieldInstance = &typeInstance->mFieldInstances.back();
|
auto fieldInstance = &typeInstance->mFieldInstances.back();
|
||||||
|
@ -2705,9 +2707,14 @@ void BfIRBuilder::CreateTypeDefinition(BfType* type, bool forceDefine)
|
||||||
if (typeInstance->IsBoxed())
|
if (typeInstance->IsBoxed())
|
||||||
{
|
{
|
||||||
auto boxedType = (BfBoxedType*)typeInstance;
|
auto boxedType = (BfBoxedType*)typeInstance;
|
||||||
if (!boxedType->mElementType->IsValuelessType())
|
BF_ASSERT(!boxedType->mFieldInstances.IsEmpty());
|
||||||
|
|
||||||
|
auto& fieldInst = boxedType->mFieldInstances.back();
|
||||||
|
auto elementType = fieldInst.mResolvedType;
|
||||||
|
|
||||||
|
if (!elementType->IsValuelessType())
|
||||||
{
|
{
|
||||||
irFieldTypes.push_back(MapTypeInst(boxedType->mElementType, boxedType->mElementType->IsValueType() ? BfIRPopulateType_Eventually_Full : BfIRPopulateType_Declaration));
|
irFieldTypes.push_back(MapType(elementType, elementType->IsValueType() ? BfIRPopulateType_Eventually_Full : BfIRPopulateType_Declaration));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -331,7 +331,7 @@ void BfGNUMangler::MangleTypeInst(MangleContext& mangleContext, StringImpl& name
|
||||||
auto boxedType = (BfBoxedType*)typeInst;
|
auto boxedType = (BfBoxedType*)typeInst;
|
||||||
name += "N3BoxI";
|
name += "N3BoxI";
|
||||||
mangleContext.mSubstituteList.push_back(NameSubstitute(BfGNUMangler::NameSubstitute::Kind_None, NULL)); // Insert entry for 'Box'
|
mangleContext.mSubstituteList.push_back(NameSubstitute(BfGNUMangler::NameSubstitute::Kind_None, NULL)); // Insert entry for 'Box'
|
||||||
Mangle(mangleContext, name, boxedType->mElementType, postfixTypeInstance);
|
Mangle(mangleContext, name, boxedType->GetModifiedElementType(), postfixTypeInstance);
|
||||||
name += "E";
|
name += "E";
|
||||||
mangleContext.mSubstituteList.push_back(NameSubstitute(BfGNUMangler::NameSubstitute::Kind_None, NULL)); // Insert entry for 'Box<T>'
|
mangleContext.mSubstituteList.push_back(NameSubstitute(BfGNUMangler::NameSubstitute::Kind_None, NULL)); // Insert entry for 'Box<T>'
|
||||||
if (isEndOpen != NULL)
|
if (isEndOpen != NULL)
|
||||||
|
@ -1158,7 +1158,7 @@ bool BfMSMangler::FindOrCreateNameSub(MangleContext& mangleContext, StringImpl&
|
||||||
auto boxedType = (BfBoxedType*)newNameSub.mTypeInst;
|
auto boxedType = (BfBoxedType*)newNameSub.mTypeInst;
|
||||||
name += "?$Box@";
|
name += "?$Box@";
|
||||||
BfTypeVector typeVec;
|
BfTypeVector typeVec;
|
||||||
typeVec.push_back(boxedType->mElementType);
|
typeVec.push_back(boxedType->GetModifiedElementType());
|
||||||
AddGenericArgs(mangleContext, name, typeVec);
|
AddGenericArgs(mangleContext, name, typeVec);
|
||||||
name += '@';
|
name += '@';
|
||||||
}
|
}
|
||||||
|
|
|
@ -1130,7 +1130,7 @@ void BfModule::EnsureIRBuilder(bool dbgVerifyCodeGen)
|
||||||
// code as we walk the AST
|
// code as we walk the AST
|
||||||
//mBfIRBuilder->mDbgVerifyCodeGen = true;
|
//mBfIRBuilder->mDbgVerifyCodeGen = true;
|
||||||
if (
|
if (
|
||||||
(mModuleName == "-")
|
(mModuleName == "Program")
|
||||||
//|| (mModuleName == "System_Internal")
|
//|| (mModuleName == "System_Internal")
|
||||||
//|| (mModuleName == "vdata")
|
//|| (mModuleName == "vdata")
|
||||||
//|| (mModuleName == "Hey_Dude_Bro_TestClass")
|
//|| (mModuleName == "Hey_Dude_Bro_TestClass")
|
||||||
|
@ -1583,6 +1583,17 @@ int BfModule::GetStringPoolIdx(BfIRValue constantStr, BfIRConstHolder* constHold
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String* BfModule::GetStringPoolString(BfIRValue constantStr, BfIRConstHolder * constHolder)
|
||||||
|
{
|
||||||
|
int strId = GetStringPoolIdx(constantStr, constHolder);
|
||||||
|
if (strId != -1)
|
||||||
|
{
|
||||||
|
auto& entry = mContext->mStringObjectIdMap[strId];
|
||||||
|
return &entry.mString;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
BfIRValue BfModule::GetStringCharPtr(int stringId)
|
BfIRValue BfModule::GetStringCharPtr(int stringId)
|
||||||
{
|
{
|
||||||
BfIRValue* irValue = NULL;
|
BfIRValue* irValue = NULL;
|
||||||
|
@ -4264,10 +4275,6 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
|
||||||
|
|
||||||
BfTypeInstance* typeInstance = type->ToTypeInstance();
|
BfTypeInstance* typeInstance = type->ToTypeInstance();
|
||||||
|
|
||||||
// BfType* typeInstanceType = ResolveTypeDef(mCompiler->mReflectTypeInstanceTypeDef, BfPopulateType_Identity);
|
|
||||||
// mBfIRBuilder->PopulateType(typeInstanceType, BfIRPopulateType_Full_ForceDefinition);
|
|
||||||
// PopulateType(typeInstanceType);
|
|
||||||
|
|
||||||
BfType* typeInstanceType = ResolveTypeDef(mCompiler->mReflectTypeInstanceTypeDef);
|
BfType* typeInstanceType = ResolveTypeDef(mCompiler->mReflectTypeInstanceTypeDef);
|
||||||
mBfIRBuilder->PopulateType(typeInstanceType, BfIRPopulateType_Full_ForceDefinition);
|
mBfIRBuilder->PopulateType(typeInstanceType, BfIRPopulateType_Full_ForceDefinition);
|
||||||
|
|
||||||
|
@ -4379,7 +4386,11 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
|
||||||
if (type->IsStruct())
|
if (type->IsStruct())
|
||||||
typeFlags |= BfTypeFlags_Struct;
|
typeFlags |= BfTypeFlags_Struct;
|
||||||
if (type->IsBoxed())
|
if (type->IsBoxed())
|
||||||
|
{
|
||||||
typeFlags |= BfTypeFlags_Boxed;
|
typeFlags |= BfTypeFlags_Boxed;
|
||||||
|
if (((BfBoxedType*)type)->IsBoxedStructPtr())
|
||||||
|
typeFlags |= BfTypeFlags_Pointer;
|
||||||
|
}
|
||||||
if (type->IsPrimitiveType())
|
if (type->IsPrimitiveType())
|
||||||
typeFlags |= BfTypeFlags_Primitive;
|
typeFlags |= BfTypeFlags_Primitive;
|
||||||
if (type->IsTypedPrimitive())
|
if (type->IsTypedPrimitive())
|
||||||
|
@ -4573,10 +4584,11 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
|
||||||
{
|
{
|
||||||
if (interfaceEntry.mInterfaceType->mSlotNum >= 0)
|
if (interfaceEntry.mInterfaceType->mSlotNum >= 0)
|
||||||
{
|
{
|
||||||
|
if (dynCastData[interfaceEntry.mInterfaceType->mSlotNum + 1] == 0)
|
||||||
dynCastData[interfaceEntry.mInterfaceType->mSlotNum + 1] = interfaceEntry.mInterfaceType->mTypeId;
|
dynCastData[interfaceEntry.mInterfaceType->mSlotNum + 1] = interfaceEntry.mInterfaceType->mTypeId;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
checkTypeInst = checkTypeInst->mBaseType;
|
checkTypeInst = checkTypeInst->GetImplBaseType();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mSystem->mPtrSize == 8)
|
if (mSystem->mPtrSize == 8)
|
||||||
|
@ -4633,6 +4645,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
|
||||||
Dictionary<BfTypeInstance*, _InterfaceMatchEntry> interfaceMap;
|
Dictionary<BfTypeInstance*, _InterfaceMatchEntry> interfaceMap;
|
||||||
auto checkTypeInst = typeInstance;
|
auto checkTypeInst = typeInstance;
|
||||||
|
|
||||||
|
bool forceInterfaceSet = false;
|
||||||
while (checkTypeInst != NULL)
|
while (checkTypeInst != NULL)
|
||||||
{
|
{
|
||||||
for (auto&& interfaceEntry : checkTypeInst->mInterfaces)
|
for (auto&& interfaceEntry : checkTypeInst->mInterfaces)
|
||||||
|
@ -4648,6 +4661,11 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
|
||||||
auto prevEntry = matchEntry->mEntry;
|
auto prevEntry = matchEntry->mEntry;
|
||||||
bool isBetter = TypeIsSubTypeOf(checkTypeInst, matchEntry->mEntrySource);
|
bool isBetter = TypeIsSubTypeOf(checkTypeInst, matchEntry->mEntrySource);
|
||||||
bool isWorse = TypeIsSubTypeOf(matchEntry->mEntrySource, checkTypeInst);
|
bool isWorse = TypeIsSubTypeOf(matchEntry->mEntrySource, checkTypeInst);
|
||||||
|
if (forceInterfaceSet)
|
||||||
|
{
|
||||||
|
isBetter = true;
|
||||||
|
isWorse = false;
|
||||||
|
}
|
||||||
if (isBetter == isWorse)
|
if (isBetter == isWorse)
|
||||||
CompareDeclTypes(interfaceEntry.mDeclaringType, prevEntry->mDeclaringType, isBetter, isWorse);
|
CompareDeclTypes(interfaceEntry.mDeclaringType, prevEntry->mDeclaringType, isBetter, isWorse);
|
||||||
if (isBetter == isWorse)
|
if (isBetter == isWorse)
|
||||||
|
@ -4675,7 +4693,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
checkTypeInst = checkTypeInst->mBaseType;
|
checkTypeInst = checkTypeInst->GetImplBaseType();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto interfacePair : interfaceMap)
|
for (auto interfacePair : interfaceMap)
|
||||||
|
@ -4701,7 +4719,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
|
||||||
while (checkTypeInst != NULL)
|
while (checkTypeInst != NULL)
|
||||||
{
|
{
|
||||||
origVirtTypeStack.push_back(checkTypeInst);
|
origVirtTypeStack.push_back(checkTypeInst);
|
||||||
checkTypeInst = checkTypeInst->mBaseType;
|
checkTypeInst = checkTypeInst->GetImplBaseType();
|
||||||
}
|
}
|
||||||
|
|
||||||
Array<BfVirtualMethodEntry> origVTable;
|
Array<BfVirtualMethodEntry> origVTable;
|
||||||
|
@ -4860,14 +4878,6 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
|
||||||
makeEmpty = true;
|
makeEmpty = true;
|
||||||
|
|
||||||
int endVirtualIdx = interfaceEntry->mStartVirtualIdx + interfaceEntry->mInterfaceType->mVirtualMethodTableSize;
|
int endVirtualIdx = interfaceEntry->mStartVirtualIdx + interfaceEntry->mInterfaceType->mVirtualMethodTableSize;
|
||||||
// for (int methodIdx = 0; methodIdx < (int)interfaceEntry->mInterfaceType->mMethodInstanceGroups.size(); methodIdx++)
|
|
||||||
// {
|
|
||||||
// BfMethodInstance* ifaceMethodInstance = interfaceEntry->mInterfaceType->mMethodInstanceGroups[methodIdx].mDefault;
|
|
||||||
// if ((ifaceMethodInstance == NULL) || (ifaceMethodInstance->mVirtualTableIdx == -1))
|
|
||||||
// continue;
|
|
||||||
// endVirtualIdx = BF_MAX(endVirtualIdx, interfaceEntry->mStartVirtualIdx + ifaceMethodInstance->mVirtualTableIdx);
|
|
||||||
// }
|
|
||||||
|
|
||||||
bool useExt = endVirtualIdx > ifaceMethodExtStart;
|
bool useExt = endVirtualIdx > ifaceMethodExtStart;
|
||||||
|
|
||||||
for (int methodIdx = 0; methodIdx < (int)interfaceEntry->mInterfaceType->mMethodInstanceGroups.size(); methodIdx++)
|
for (int methodIdx = 0; methodIdx < (int)interfaceEntry->mInterfaceType->mMethodInstanceGroups.size(); methodIdx++)
|
||||||
|
@ -4894,7 +4904,6 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
|
||||||
BF_ASSERT(methodInstance->mIsReified);
|
BF_ASSERT(methodInstance->mIsReified);
|
||||||
// This doesn't work because we may have FOREIGN methods from implicit interface methods
|
// This doesn't work because we may have FOREIGN methods from implicit interface methods
|
||||||
//auto moduleMethodInst = GetMethodInstanceAtIdx(methodRef.mTypeInstance, methodRef.mMethodNum);
|
//auto moduleMethodInst = GetMethodInstanceAtIdx(methodRef.mTypeInstance, methodRef.mMethodNum);
|
||||||
BfMethodInstance* methodInstance = methodRef;
|
|
||||||
auto moduleMethodInst = ReferenceExternalMethodInstance(methodInstance);
|
auto moduleMethodInst = ReferenceExternalMethodInstance(methodInstance);
|
||||||
auto funcPtr = mBfIRBuilder->CreateBitCast(moduleMethodInst.mFunc, voidPtrIRType);
|
auto funcPtr = mBfIRBuilder->CreateBitCast(moduleMethodInst.mFunc, voidPtrIRType);
|
||||||
pushValue = funcPtr;
|
pushValue = funcPtr;
|
||||||
|
@ -4906,8 +4915,6 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
|
||||||
}
|
}
|
||||||
|
|
||||||
int idx = interfaceEntry->mStartVirtualIdx + ifaceMethodInstance->mVirtualTableIdx;
|
int idx = interfaceEntry->mStartVirtualIdx + ifaceMethodInstance->mVirtualTableIdx;
|
||||||
// if (!useExt)
|
|
||||||
// vData[iFaceMethodStartIdx + idx] = pushValue;
|
|
||||||
if (idx < ifaceMethodExtStart)
|
if (idx < ifaceMethodExtStart)
|
||||||
{
|
{
|
||||||
BF_ASSERT(iFaceMethodStartIdx + idx < (int)vData.size());
|
BF_ASSERT(iFaceMethodStartIdx + idx < (int)vData.size());
|
||||||
|
@ -4924,6 +4931,45 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (typeInstance->IsBoxed())
|
||||||
|
{
|
||||||
|
BfBoxedType* boxedType = (BfBoxedType*)typeInstance;
|
||||||
|
if (boxedType->IsBoxedStructPtr())
|
||||||
|
{
|
||||||
|
// Force override of GetHashCode so we use the pointer address as the hash code
|
||||||
|
checkTypeInst = CreateBoxedType(ResolveTypeDef(mCompiler->mPointerTypeDef));
|
||||||
|
|
||||||
|
// Force override of GetHashCode so we use the pointer address as the hash code
|
||||||
|
for (auto& checkIFace : checkTypeInst->mInterfaces)
|
||||||
|
{
|
||||||
|
for (int methodIdx = 0; methodIdx < (int)checkIFace.mInterfaceType->mMethodInstanceGroups.size(); methodIdx++)
|
||||||
|
{
|
||||||
|
BfIRValue pushValue;
|
||||||
|
|
||||||
|
BfMethodInstance* ifaceMethodInstance = checkIFace.mInterfaceType->mMethodInstanceGroups[methodIdx].mDefault;
|
||||||
|
if ((ifaceMethodInstance == NULL) || (ifaceMethodInstance->mVirtualTableIdx == -1))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if ((!ifaceMethodInstance->mIsReified) || (!ifaceMethodInstance->mMethodInstanceGroup->IsImplemented()))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
auto& methodRef = checkTypeInst->mInterfaceMethodTable[checkIFace.mStartInterfaceTableIdx + methodIdx].mMethodRef;
|
||||||
|
|
||||||
|
auto methodInstance = (BfMethodInstance*)methodRef;
|
||||||
|
BF_ASSERT(methodInstance->mIsReified);
|
||||||
|
// This doesn't work because we may have FOREIGN methods from implicit interface methods
|
||||||
|
//auto moduleMethodInst = GetMethodInstanceAtIdx(methodRef.mTypeInstance, methodRef.mMethodNum);
|
||||||
|
auto moduleMethodInst = ReferenceExternalMethodInstance(methodInstance);
|
||||||
|
auto funcPtr = mBfIRBuilder->CreateBitCast(moduleMethodInst.mFunc, voidPtrIRType);
|
||||||
|
|
||||||
|
int idx = checkIFace.mStartVirtualIdx + ifaceMethodInstance->mVirtualTableIdx;
|
||||||
|
vData[iFaceMethodStartIdx + idx] = funcPtr;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ((needsVData) && (!typeInstance->mTypeDef->mIsStatic))
|
if ((needsVData) && (!typeInstance->mTypeDef->mIsStatic))
|
||||||
{
|
{
|
||||||
BfIRValue ifaceMethodExtVar;
|
BfIRValue ifaceMethodExtVar;
|
||||||
|
@ -6541,7 +6587,15 @@ bool BfModule::CheckGenericConstraints(const BfGenericParamSource& genericParamS
|
||||||
|
|
||||||
BfTypeInstance* typeConstraintInst = convCheckConstraint->ToTypeInstance();
|
BfTypeInstance* typeConstraintInst = convCheckConstraint->ToTypeInstance();
|
||||||
|
|
||||||
bool implementsInterface = CanImplicitlyCast(checkArgType, convCheckConstraint);
|
bool implementsInterface = false;
|
||||||
|
if (origCheckArgType != checkArgType)
|
||||||
|
{
|
||||||
|
implementsInterface = CanImplicitlyCast(origCheckArgType, convCheckConstraint);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!implementsInterface)
|
||||||
|
implementsInterface = CanImplicitlyCast(checkArgType, convCheckConstraint);
|
||||||
|
|
||||||
if ((!implementsInterface) && (origCheckArgType->IsWrappableType()))
|
if ((!implementsInterface) && (origCheckArgType->IsWrappableType()))
|
||||||
{
|
{
|
||||||
BfTypeInstance* wrappedStructType = GetWrappedStructType(origCheckArgType, false);
|
BfTypeInstance* wrappedStructType = GetWrappedStructType(origCheckArgType, false);
|
||||||
|
@ -8228,23 +8282,40 @@ BfTypedValue BfModule::BoxValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp
|
||||||
return BfTypedValue(phi, resultType);
|
return BfTypedValue(phi, resultType);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fromStructTypeInstance == NULL)
|
bool alreadyCheckedCast = false;
|
||||||
{
|
|
||||||
auto primType = (BfPrimitiveType*) typedVal.mType;
|
|
||||||
fromStructTypeInstance = GetWrappedStructType(typedVal.mType);
|
|
||||||
}
|
|
||||||
if (fromStructTypeInstance == NULL)
|
|
||||||
return BfTypedValue();
|
|
||||||
BfTypeInstance* toTypeInstance = NULL;
|
BfTypeInstance* toTypeInstance = NULL;
|
||||||
if (toType != NULL)
|
if (toType != NULL)
|
||||||
toTypeInstance = toType->ToTypeInstance();
|
toTypeInstance = toType->ToTypeInstance();
|
||||||
|
|
||||||
// Need to box it
|
bool isStructPtr = typedVal.mType->IsStructPtr();
|
||||||
bool isBoxedType = (fromStructTypeInstance != NULL) && (toType->IsBoxed()) && (CreateBoxedType(fromStructTypeInstance) == toType);
|
if (fromStructTypeInstance == NULL)
|
||||||
|
|
||||||
if ((toType == NULL) || (toType == mContext->mBfObjectType) || (isBoxedType) || (TypeIsSubTypeOf(fromStructTypeInstance, toTypeInstance)))
|
|
||||||
{
|
{
|
||||||
auto boxedType = CreateBoxedType(fromStructTypeInstance);
|
auto primType = (BfPrimitiveType*)typedVal.mType;
|
||||||
|
fromStructTypeInstance = GetWrappedStructType(typedVal.mType);
|
||||||
|
|
||||||
|
if (isStructPtr)
|
||||||
|
{
|
||||||
|
if ((toTypeInstance != NULL) && (TypeIsSubTypeOf(fromStructTypeInstance, toTypeInstance)))
|
||||||
|
alreadyCheckedCast = true;
|
||||||
|
|
||||||
|
fromStructTypeInstance = typedVal.mType->GetUnderlyingType()->ToTypeInstance();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (fromStructTypeInstance == NULL)
|
||||||
|
return BfTypedValue();
|
||||||
|
|
||||||
|
// Need to box it
|
||||||
|
auto boxedType = CreateBoxedType(typedVal.mType);
|
||||||
|
bool isBoxedType = (fromStructTypeInstance != NULL) && (toType->IsBoxed()) && (boxedType == toType);
|
||||||
|
|
||||||
|
if ((toType == NULL) || (toType == mContext->mBfObjectType) || (isBoxedType) || (alreadyCheckedCast) || (TypeIsSubTypeOf(fromStructTypeInstance, toTypeInstance)))
|
||||||
|
{
|
||||||
|
if (typedVal.mType->IsPointer())
|
||||||
|
{
|
||||||
|
NOP;
|
||||||
|
}
|
||||||
|
|
||||||
mBfIRBuilder->PopulateType(boxedType);
|
mBfIRBuilder->PopulateType(boxedType);
|
||||||
AddDependency(boxedType, mCurTypeInstance, BfDependencyMap::DependencyFlag_ReadFields);
|
AddDependency(boxedType, mCurTypeInstance, BfDependencyMap::DependencyFlag_ReadFields);
|
||||||
auto allocaInst = AllocFromType(boxedType, allocTarget, BfIRValue(), BfIRValue(), 0, callDtor ? BfAllocFlags_None : BfAllocFlags_NoDtorCall);
|
auto allocaInst = AllocFromType(boxedType, allocTarget, BfIRValue(), BfIRValue(), 0, callDtor ? BfAllocFlags_None : BfAllocFlags_NoDtorCall);
|
||||||
|
@ -8264,7 +8335,7 @@ BfTypedValue BfModule::BoxValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp
|
||||||
typedVal = LoadValue(typedVal);
|
typedVal = LoadValue(typedVal);
|
||||||
auto valPtr = mBfIRBuilder->CreateInBoundsGEP(allocaInst, 0, 1);
|
auto valPtr = mBfIRBuilder->CreateInBoundsGEP(allocaInst, 0, 1);
|
||||||
|
|
||||||
if (typedVal.mType != fromStructTypeInstance)
|
if ((typedVal.mType != fromStructTypeInstance) && (!isStructPtr))
|
||||||
{
|
{
|
||||||
auto ptrType = CreatePointerType(typedVal.mType);
|
auto ptrType = CreatePointerType(typedVal.mType);
|
||||||
valPtr = mBfIRBuilder->CreateBitCast(valPtr, mBfIRBuilder->MapType(ptrType));
|
valPtr = mBfIRBuilder->CreateBitCast(valPtr, mBfIRBuilder->MapType(ptrType));
|
||||||
|
@ -16573,6 +16644,12 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup)
|
||||||
{
|
{
|
||||||
BfIRValue thisValue = mBfIRBuilder->CreateInBoundsGEP(mCurMethodState->mLocals[0]->mValue, 0, 1);
|
BfIRValue thisValue = mBfIRBuilder->CreateInBoundsGEP(mCurMethodState->mLocals[0]->mValue, 0, 1);
|
||||||
BfTypedValue innerVal(thisValue, innerType, true);
|
BfTypedValue innerVal(thisValue, innerType, true);
|
||||||
|
if (boxedType->IsBoxedStructPtr())
|
||||||
|
{
|
||||||
|
innerVal = LoadValue(innerVal);
|
||||||
|
innerVal = BfTypedValue(innerVal.mValue, innerType, true);
|
||||||
|
}
|
||||||
|
|
||||||
exprEvaluator.PushThis(NULL, innerVal, innerMethodInstance.mMethodInstance, innerParams);
|
exprEvaluator.PushThis(NULL, innerVal, innerMethodInstance.mMethodInstance, innerParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1388,6 +1388,7 @@ public:
|
||||||
BfIRValue CreateStringObjectValue(const StringImpl& str, int stringId, bool define);
|
BfIRValue CreateStringObjectValue(const StringImpl& str, int stringId, bool define);
|
||||||
BfIRValue CreateStringCharPtr(const StringImpl& str, int stringId, bool define);
|
BfIRValue CreateStringCharPtr(const StringImpl& str, int stringId, bool define);
|
||||||
int GetStringPoolIdx(BfIRValue constantStr, BfIRConstHolder* constHolder = NULL);
|
int GetStringPoolIdx(BfIRValue constantStr, BfIRConstHolder* constHolder = NULL);
|
||||||
|
String* GetStringPoolString(BfIRValue constantStr, BfIRConstHolder* constHolder = NULL);
|
||||||
BfIRValue GetStringCharPtr(int stringId);
|
BfIRValue GetStringCharPtr(int stringId);
|
||||||
BfIRValue GetStringCharPtr(BfIRValue strValue);
|
BfIRValue GetStringCharPtr(BfIRValue strValue);
|
||||||
BfIRValue GetStringCharPtr(const StringImpl& str);
|
BfIRValue GetStringCharPtr(const StringImpl& str);
|
||||||
|
|
|
@ -1749,11 +1749,6 @@ bool BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
|
||||||
if (baseType != NULL)
|
if (baseType != NULL)
|
||||||
defaultBaseTypeInst = baseType->ToTypeInstance();
|
defaultBaseTypeInst = baseType->ToTypeInstance();
|
||||||
|
|
||||||
if (typeInstance->mTypeId == 260)
|
|
||||||
{
|
|
||||||
NOP;
|
|
||||||
}
|
|
||||||
|
|
||||||
BfTypeReference* baseTypeRef = NULL;
|
BfTypeReference* baseTypeRef = NULL;
|
||||||
if ((typeDef->mIsDelegate) && (!typeInstance->IsClosure()))
|
if ((typeDef->mIsDelegate) && (!typeInstance->IsClosure()))
|
||||||
{
|
{
|
||||||
|
@ -1902,6 +1897,18 @@ bool BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
|
||||||
|
|
||||||
if (resolvedTypeRef->IsBoxed())
|
if (resolvedTypeRef->IsBoxed())
|
||||||
{
|
{
|
||||||
|
if ((baseType != NULL) && (baseType->IsStruct()))
|
||||||
|
{
|
||||||
|
BfBoxedType* boxedType = (BfBoxedType*)resolvedTypeRef;
|
||||||
|
BfType* modifiedBaseType = baseType;
|
||||||
|
if (boxedType->IsBoxedStructPtr())
|
||||||
|
modifiedBaseType = CreatePointerType(modifiedBaseType);
|
||||||
|
boxedType->mBoxedBaseType = CreateBoxedType(modifiedBaseType);
|
||||||
|
|
||||||
|
PopulateType(boxedType->mBoxedBaseType);
|
||||||
|
AddDependency(boxedType->mBoxedBaseType, typeInstance, BfDependencyMap::DependencyFlag_DerivedFrom);
|
||||||
|
}
|
||||||
|
|
||||||
baseType = mContext->mBfObjectType;
|
baseType = mContext->mBfObjectType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2097,16 +2104,18 @@ bool BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
|
||||||
if (resolvedTypeRef->IsBoxed())
|
if (resolvedTypeRef->IsBoxed())
|
||||||
{
|
{
|
||||||
BfBoxedType* boxedType = (BfBoxedType*)resolvedTypeRef;
|
BfBoxedType* boxedType = (BfBoxedType*)resolvedTypeRef;
|
||||||
BfTypeInstance* innerType = boxedType->mElementType->ToTypeInstance();
|
BfType* innerType = boxedType->mElementType;
|
||||||
|
if (boxedType->IsBoxedStructPtr())
|
||||||
|
innerType = CreatePointerType(innerType);
|
||||||
if (innerType->IsIncomplete())
|
if (innerType->IsIncomplete())
|
||||||
PopulateType(innerType, BfPopulateType_Data);
|
PopulateType(innerType, BfPopulateType_Data);
|
||||||
|
|
||||||
auto baseType = typeInstance->mBaseType;
|
auto baseType = typeInstance->mBaseType;
|
||||||
dataPos = baseType->mInstSize;
|
dataPos = baseType->mInstSize;
|
||||||
int alignSize = std::max(innerType->mInstAlign, baseType->mInstAlign);
|
int alignSize = BF_MAX(innerType->mAlign, baseType->mInstAlign);
|
||||||
if (alignSize > 1)
|
if (alignSize > 1)
|
||||||
dataPos = (dataPos + (alignSize - 1)) & ~(alignSize - 1);
|
dataPos = (dataPos + (alignSize - 1)) & ~(alignSize - 1);
|
||||||
int dataSize = innerType->mInstSize;
|
int dataSize = innerType->mSize;
|
||||||
|
|
||||||
typeInstance->mFieldInstances.push_back(BfFieldInstance());
|
typeInstance->mFieldInstances.push_back(BfFieldInstance());
|
||||||
BfFieldInstance* fieldInstance = &typeInstance->mFieldInstances.back();
|
BfFieldInstance* fieldInstance = &typeInstance->mFieldInstances.back();
|
||||||
|
@ -2946,25 +2955,47 @@ bool BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
|
||||||
BfLogSysM("Setting underlying type %p %d\n", typeInstance, underlyingTypeDeferred);
|
BfLogSysM("Setting underlying type %p %d\n", typeInstance, underlyingTypeDeferred);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (underlyingTypeDeferred)
|
if (typeInstance->IsEnum())
|
||||||
{
|
{
|
||||||
int64 min = 0;
|
int64 min = 0;
|
||||||
int64 max = 0;
|
int64 max = 0;
|
||||||
|
|
||||||
|
bool isFirst = false;
|
||||||
|
|
||||||
|
if (typeInstance->mTypeInfoEx == NULL)
|
||||||
|
typeInstance->mTypeInfoEx = new BfTypeInfoEx();
|
||||||
|
|
||||||
for (auto& fieldInstanceRef : typeInstance->mFieldInstances)
|
for (auto& fieldInstanceRef : typeInstance->mFieldInstances)
|
||||||
{
|
{
|
||||||
auto fieldInstance = &fieldInstanceRef;
|
auto fieldInstance = &fieldInstanceRef;
|
||||||
auto fieldDef = fieldInstance->GetFieldDef();
|
auto fieldDef = fieldInstance->GetFieldDef();
|
||||||
if ((fieldDef != NULL) && (fieldDef->IsEnumCaseEntry()))
|
if ((fieldDef != NULL) && (fieldDef->IsEnumCaseEntry()))
|
||||||
{
|
{
|
||||||
auto constant = typeInstance->mConstHolder->GetConstantById(fieldInstance->mConstIdx);
|
if (fieldInstance->mConstIdx == -1)
|
||||||
BF_ASSERT(constant->mTypeCode == BfTypeCode_Int64);
|
continue;
|
||||||
|
|
||||||
|
auto constant = typeInstance->mConstHolder->GetConstantById(fieldInstance->mConstIdx);
|
||||||
|
BF_ASSERT((constant->mTypeCode == BfTypeCode_Int64) || (!underlyingTypeDeferred));
|
||||||
|
|
||||||
|
if (isFirst)
|
||||||
|
{
|
||||||
|
min = constant->mInt64;
|
||||||
|
max = constant->mInt64;
|
||||||
|
isFirst = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
min = BF_MIN(constant->mInt64, min);
|
min = BF_MIN(constant->mInt64, min);
|
||||||
max = BF_MAX(constant->mInt64, max);
|
max = BF_MAX(constant->mInt64, max);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
typeInstance->mTypeInfoEx->mMinValue = min;
|
||||||
|
typeInstance->mTypeInfoEx->mMaxValue = max;
|
||||||
|
|
||||||
|
if (underlyingTypeDeferred)
|
||||||
|
{
|
||||||
BfTypeCode typeCode;
|
BfTypeCode typeCode;
|
||||||
|
|
||||||
if ((min >= -0x80) && (max <= 0x7F))
|
if ((min >= -0x80) && (max <= 0x7F))
|
||||||
|
@ -3001,6 +3032,8 @@ bool BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
|
||||||
fieldInstance->mResolvedType = underlyingType;
|
fieldInstance->mResolvedType = underlyingType;
|
||||||
fieldInstance->mDataSize = underlyingType->mSize;
|
fieldInstance->mDataSize = underlyingType->mSize;
|
||||||
|
|
||||||
|
typeInstance->mTypeInfoEx->mUnderlyingType = underlyingType;
|
||||||
|
|
||||||
typeInstance->mSize = underlyingType->mSize;
|
typeInstance->mSize = underlyingType->mSize;
|
||||||
typeInstance->mAlign = underlyingType->mAlign;
|
typeInstance->mAlign = underlyingType->mAlign;
|
||||||
typeInstance->mInstSize = underlyingType->mSize;
|
typeInstance->mInstSize = underlyingType->mSize;
|
||||||
|
@ -3008,6 +3041,11 @@ bool BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
|
||||||
|
|
||||||
typeInstance->mRebuildFlags = (BfTypeRebuildFlags)(typeInstance->mRebuildFlags & ~BfTypeRebuildFlag_UnderlyingTypeDeferred);
|
typeInstance->mRebuildFlags = (BfTypeRebuildFlags)(typeInstance->mRebuildFlags & ~BfTypeRebuildFlag_UnderlyingTypeDeferred);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
BF_ASSERT(!underlyingTypeDeferred);
|
||||||
|
}
|
||||||
|
|
||||||
if ((typeInstance->IsPayloadEnum()) && (!typeInstance->IsBoxed()))
|
if ((typeInstance->IsPayloadEnum()) && (!typeInstance->IsBoxed()))
|
||||||
{
|
{
|
||||||
|
@ -3104,33 +3142,8 @@ bool BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: We moved this to much earlier in InitType
|
if (typeInstance == mContext->mBfObjectType)
|
||||||
// This allows us to properly deleted a dependent generic type if a typeGenericArg gets deleted.
|
typeInstance->mHasBeenInstantiated = true;
|
||||||
//...
|
|
||||||
// Add generic dependencies if needed
|
|
||||||
// auto genericTypeInstance = typeInstance->ToGenericTypeInstance();
|
|
||||||
// if (genericTypeInstance != NULL)
|
|
||||||
// {
|
|
||||||
// for (auto genericType : genericTypeInstance->mTypeGenericArguments)
|
|
||||||
// {
|
|
||||||
// if (genericType->IsPrimitiveType())
|
|
||||||
// genericType = GetWrappedStructType(genericType);
|
|
||||||
// if (genericType != NULL)
|
|
||||||
// {
|
|
||||||
// AddDependency(genericType, genericTypeInstance, BfDependencyMap::DependencyFlag_TypeGenericArg);
|
|
||||||
// BfLogSysM("Adding generic dependency of %p for type %p\n", genericTypeInstance, genericTypeInstance);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// if (typeInstance->IsSpecializedType())
|
|
||||||
// {
|
|
||||||
// // This ensures we rebuild the unspecialized type whenever the specialized type rebuilds. This is important
|
|
||||||
// // for generic type binding
|
|
||||||
// auto unspecializedTypeInstance = GetUnspecializedTypeInstance(typeInstance);
|
|
||||||
// BF_ASSERT(!unspecializedTypeInstance->IsUnspecializedTypeVariation());
|
|
||||||
// mContext->mScratchModule->AddDependency(typeInstance, unspecializedTypeInstance, BfDependencyMap::DependencyFlag_UnspecializedType);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
if (populateType == BfPopulateType_Data)
|
if (populateType == BfPopulateType_Data)
|
||||||
return true;
|
return true;
|
||||||
|
@ -3181,16 +3194,16 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance)
|
||||||
}
|
}
|
||||||
|
|
||||||
int newIntefaceStartIdx = 0;
|
int newIntefaceStartIdx = 0;
|
||||||
auto baseType = typeInstance->mBaseType;
|
auto implBaseType = typeInstance->GetImplBaseType();
|
||||||
if (baseType != NULL)
|
if (implBaseType != NULL)
|
||||||
{
|
{
|
||||||
auto baseTypeInst = baseType->ToTypeInstance();
|
auto baseTypeInst = implBaseType->ToTypeInstance();
|
||||||
if (baseType->IsIncomplete())
|
if (implBaseType->IsIncomplete())
|
||||||
PopulateType(baseType, BfPopulateType_Full_Force);
|
PopulateType(implBaseType, BfPopulateType_Full_Force);
|
||||||
|
|
||||||
typeInstance->mInterfaceMethodTable = baseTypeInst->mInterfaceMethodTable;
|
typeInstance->mInterfaceMethodTable = baseTypeInst->mInterfaceMethodTable;
|
||||||
typeInstance->mVirtualMethodTable = baseType->mVirtualMethodTable;
|
typeInstance->mVirtualMethodTable = implBaseType->mVirtualMethodTable;
|
||||||
typeInstance->mVirtualMethodTableSize = baseType->mVirtualMethodTableSize;
|
typeInstance->mVirtualMethodTableSize = implBaseType->mVirtualMethodTableSize;
|
||||||
if ((!mCompiler->IsHotCompile()) && (!mCompiler->mPassInstance->HasFailed()) && ((mCompiler->mResolvePassData == NULL) || (mCompiler->mResolvePassData->mAutoComplete == NULL)))
|
if ((!mCompiler->IsHotCompile()) && (!mCompiler->mPassInstance->HasFailed()) && ((mCompiler->mResolvePassData == NULL) || (mCompiler->mResolvePassData->mAutoComplete == NULL)))
|
||||||
{
|
{
|
||||||
BF_ASSERT(typeInstance->mVirtualMethodTable.size() == typeInstance->mVirtualMethodTableSize);
|
BF_ASSERT(typeInstance->mVirtualMethodTable.size() == typeInstance->mVirtualMethodTableSize);
|
||||||
|
@ -3231,7 +3244,7 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance)
|
||||||
{
|
{
|
||||||
AddDependency(interfaceEntry.mInterfaceType, typeInstance, BfDependencyMap::DependencyFlag_ImplementsInterface);
|
AddDependency(interfaceEntry.mInterfaceType, typeInstance, BfDependencyMap::DependencyFlag_ImplementsInterface);
|
||||||
}
|
}
|
||||||
checkTypeInstance = checkTypeInstance->mBaseType;
|
checkTypeInstance = checkTypeInstance->GetImplBaseType();
|
||||||
}
|
}
|
||||||
|
|
||||||
//for (auto& intefaceInst : typeInstance->mInterfaces)
|
//for (auto& intefaceInst : typeInstance->mInterfaces)
|
||||||
|
@ -3241,11 +3254,16 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance)
|
||||||
BF_ASSERT(typeInstance->mInterfaceMethodTable.size() == 1);
|
BF_ASSERT(typeInstance->mInterfaceMethodTable.size() == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (typeInstance->mTypeDef == mCompiler->mPointerTypeDef)
|
||||||
|
{
|
||||||
|
NOP;
|
||||||
|
}
|
||||||
|
|
||||||
// Slot interfaces method blocks in vtable
|
// Slot interfaces method blocks in vtable
|
||||||
{
|
{
|
||||||
int ifaceVirtIdx = 0;
|
int ifaceVirtIdx = 0;
|
||||||
std::unordered_map<BfTypeInstance*, BfTypeInterfaceEntry*> interfaceMap;
|
std::unordered_map<BfTypeInstance*, BfTypeInterfaceEntry*> interfaceMap;
|
||||||
BfTypeInstance* checkType = typeInstance->mBaseType;
|
BfTypeInstance* checkType = typeInstance->GetImplBaseType();
|
||||||
while (checkType != NULL)
|
while (checkType != NULL)
|
||||||
{
|
{
|
||||||
for (auto&& ifaceEntry : checkType->mInterfaces)
|
for (auto&& ifaceEntry : checkType->mInterfaces)
|
||||||
|
@ -3253,7 +3271,7 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance)
|
||||||
interfaceMap[ifaceEntry.mInterfaceType] = &ifaceEntry;
|
interfaceMap[ifaceEntry.mInterfaceType] = &ifaceEntry;
|
||||||
ifaceVirtIdx = std::max(ifaceVirtIdx, ifaceEntry.mStartVirtualIdx + ifaceEntry.mInterfaceType->mVirtualMethodTableSize);
|
ifaceVirtIdx = std::max(ifaceVirtIdx, ifaceEntry.mStartVirtualIdx + ifaceEntry.mInterfaceType->mVirtualMethodTableSize);
|
||||||
}
|
}
|
||||||
checkType = checkType->mBaseType;
|
checkType = checkType->GetImplBaseType();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int iFaceIdx = 0; iFaceIdx < (int)typeInstance->mInterfaces.size(); iFaceIdx++)
|
for (int iFaceIdx = 0; iFaceIdx < (int)typeInstance->mInterfaces.size(); iFaceIdx++)
|
||||||
|
@ -3279,12 +3297,12 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance)
|
||||||
typeInstance->mNeedsMethodProcessing = false;
|
typeInstance->mNeedsMethodProcessing = false;
|
||||||
typeInstance->mTypeIncomplete = false;
|
typeInstance->mTypeIncomplete = false;
|
||||||
|
|
||||||
auto checkBaseType = typeInstance->mBaseType;
|
auto checkBaseType = typeInstance->GetImplBaseType();
|
||||||
while (checkBaseType != NULL)
|
while (checkBaseType != NULL)
|
||||||
{
|
{
|
||||||
PopulateType(checkBaseType, BfPopulateType_Full_Force);
|
PopulateType(checkBaseType, BfPopulateType_Full_Force);
|
||||||
BF_ASSERT((!checkBaseType->IsIncomplete()) || (checkBaseType->mTypeFailed));
|
BF_ASSERT((!checkBaseType->IsIncomplete()) || (checkBaseType->mTypeFailed));
|
||||||
checkBaseType = checkBaseType->mBaseType;
|
checkBaseType = checkBaseType->GetImplBaseType();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((mCompiler->mOptions.mHasVDataExtender) && (!typeInstance->IsInterface()))
|
if ((mCompiler->mOptions.mHasVDataExtender) && (!typeInstance->IsInterface()))
|
||||||
|
@ -3733,8 +3751,8 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance)
|
||||||
BF_ASSERT(mCompiler->mOptions.mHasVDataExtender);
|
BF_ASSERT(mCompiler->mOptions.mHasVDataExtender);
|
||||||
if (methodRef.mTypeInstance == typeInstance)
|
if (methodRef.mTypeInstance == typeInstance)
|
||||||
{
|
{
|
||||||
if (typeInstance->mBaseType != NULL)
|
if (typeInstance->GetImplBaseType() != NULL)
|
||||||
BF_ASSERT(methodIdx == (int)typeInstance->mBaseType->mVirtualMethodTableSize);
|
BF_ASSERT(methodIdx == (int)typeInstance->GetImplBaseType()->mVirtualMethodTableSize);
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -3782,7 +3800,7 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance)
|
||||||
{
|
{
|
||||||
// Attempt to find matching entries in base types
|
// Attempt to find matching entries in base types
|
||||||
ambiguityContext.mIsReslotting = true;
|
ambiguityContext.mIsReslotting = true;
|
||||||
auto checkType = typeInstance->mBaseType;
|
auto checkType = typeInstance->GetImplBaseType();
|
||||||
while (checkType != NULL)
|
while (checkType != NULL)
|
||||||
{
|
{
|
||||||
for (auto& methodGroup : checkType->mMethodInstanceGroups)
|
for (auto& methodGroup : checkType->mMethodInstanceGroups)
|
||||||
|
@ -3798,7 +3816,7 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
checkType = checkType->mBaseType;
|
checkType = checkType->GetImplBaseType();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4626,8 +4644,10 @@ BfTypeInstance* BfModule::GetPrimitiveStructType(BfTypeCode typeCode)
|
||||||
|
|
||||||
BfBoxedType* BfModule::CreateBoxedType(BfType* resolvedTypeRef)
|
BfBoxedType* BfModule::CreateBoxedType(BfType* resolvedTypeRef)
|
||||||
{
|
{
|
||||||
if (resolvedTypeRef->IsPointer())
|
bool isStructPtr = false;
|
||||||
resolvedTypeRef = ((BfPointerType*)resolvedTypeRef)->mElementType;
|
|
||||||
|
// if (resolvedTypeRef->IsPointer())
|
||||||
|
// resolvedTypeRef = ((BfPointerType*)resolvedTypeRef)->mElementType;
|
||||||
if (resolvedTypeRef->IsPrimitiveType())
|
if (resolvedTypeRef->IsPrimitiveType())
|
||||||
{
|
{
|
||||||
auto primType = (BfPrimitiveType*)resolvedTypeRef;
|
auto primType = (BfPrimitiveType*)resolvedTypeRef;
|
||||||
|
@ -4641,10 +4661,18 @@ BfBoxedType* BfModule::CreateBoxedType(BfType* resolvedTypeRef)
|
||||||
else if (resolvedTypeRef->IsPointer())
|
else if (resolvedTypeRef->IsPointer())
|
||||||
{
|
{
|
||||||
BfPointerType* pointerType = (BfPointerType*)resolvedTypeRef;
|
BfPointerType* pointerType = (BfPointerType*)resolvedTypeRef;
|
||||||
|
if (pointerType->mElementType->IsStruct())
|
||||||
|
{
|
||||||
|
resolvedTypeRef = pointerType->mElementType;
|
||||||
|
isStructPtr = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
BfTypeVector typeVector;
|
BfTypeVector typeVector;
|
||||||
typeVector.Add(pointerType->mElementType);
|
typeVector.Add(pointerType->mElementType);
|
||||||
resolvedTypeRef = ResolveTypeDef(mCompiler->mPointerTTypeDef, typeVector, BfPopulateType_Data)->ToTypeInstance();
|
resolvedTypeRef = ResolveTypeDef(mCompiler->mPointerTTypeDef, typeVector, BfPopulateType_Data)->ToTypeInstance();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else if (resolvedTypeRef->IsMethodRef())
|
else if (resolvedTypeRef->IsMethodRef())
|
||||||
{
|
{
|
||||||
BfMethodRefType* methodRefType = (BfMethodRefType*)resolvedTypeRef;
|
BfMethodRefType* methodRefType = (BfMethodRefType*)resolvedTypeRef;
|
||||||
|
@ -4670,6 +4698,7 @@ BfBoxedType* BfModule::CreateBoxedType(BfType* resolvedTypeRef)
|
||||||
boxedType->mContext = mContext;
|
boxedType->mContext = mContext;
|
||||||
boxedType->mElementType = typeInst;
|
boxedType->mElementType = typeInst;
|
||||||
boxedType->mTypeDef = boxedType->mElementType->mTypeDef;
|
boxedType->mTypeDef = boxedType->mElementType->mTypeDef;
|
||||||
|
boxedType->mBoxedFlags = isStructPtr ? BfBoxedType::BoxedFlags_StructPtr : BfBoxedType::BoxedFlags_None;
|
||||||
auto resolvedBoxedType = ResolveType(boxedType);
|
auto resolvedBoxedType = ResolveType(boxedType);
|
||||||
if (resolvedBoxedType != boxedType)
|
if (resolvedBoxedType != boxedType)
|
||||||
mContext->mBoxedTypePool.GiveBack(boxedType);
|
mContext->mBoxedTypePool.GiveBack(boxedType);
|
||||||
|
@ -6904,7 +6933,6 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula
|
||||||
auto outerType = typeDef->mOuterType;
|
auto outerType = typeDef->mOuterType;
|
||||||
BF_ASSERT(!outerType->mIsPartial);
|
BF_ASSERT(!outerType->mIsPartial);
|
||||||
if (TypeHasParent(mCurTypeInstance->mTypeDef, outerType))
|
if (TypeHasParent(mCurTypeInstance->mTypeDef, outerType))
|
||||||
|
|
||||||
{
|
{
|
||||||
BfType* checkCurType = mCurTypeInstance;
|
BfType* checkCurType = mCurTypeInstance;
|
||||||
if (checkCurType->IsBoxed())
|
if (checkCurType->IsBoxed())
|
||||||
|
@ -6975,24 +7003,6 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula
|
||||||
InitType(typeInst, populateType);
|
InitType(typeInst, populateType);
|
||||||
return ResolveTypeResult(typeRef, typeInst, populateType, resolveFlags);
|
return ResolveTypeResult(typeRef, typeInst, populateType, resolveFlags);
|
||||||
}
|
}
|
||||||
else if (auto boxedTypeRef = BfNodeDynCast<BfBoxedTypeRef>(typeRef))
|
|
||||||
{
|
|
||||||
BfBoxedType* boxedType = new BfBoxedType();
|
|
||||||
auto innerType = ResolveTypeRef(boxedTypeRef->mElementType, BfPopulateType_Declaration, BfResolveTypeRefFlag_AllowGenericParamConstValue);
|
|
||||||
if ((innerType == NULL) || (!innerType->IsStruct()))
|
|
||||||
{
|
|
||||||
Fail("Invalid box target", boxedTypeRef->mElementType);
|
|
||||||
delete boxedType;
|
|
||||||
mContext->mResolvedTypes.RemoveEntry(resolvedEntry);
|
|
||||||
return ResolveTypeResult(typeRef, NULL, populateType, resolveFlags);
|
|
||||||
}
|
|
||||||
boxedType->mElementType = innerType->ToTypeInstance();
|
|
||||||
boxedType->mTypeDef = boxedType->mElementType->mTypeDef;
|
|
||||||
resolvedEntry->mValue = boxedType;
|
|
||||||
BF_ASSERT(BfResolvedTypeSet::Hash(boxedType, &lookupCtx) == resolvedEntry->mHash);
|
|
||||||
InitType(boxedType, populateType);
|
|
||||||
return ResolveTypeResult(typeRef, boxedType, populateType, resolveFlags);
|
|
||||||
}
|
|
||||||
else if (auto arrayTypeRef = BfNodeDynCast<BfArrayTypeRef>(typeRef))
|
else if (auto arrayTypeRef = BfNodeDynCast<BfArrayTypeRef>(typeRef))
|
||||||
{
|
{
|
||||||
if (arrayTypeRef->mDimensions > 4)
|
if (arrayTypeRef->mDimensions > 4)
|
||||||
|
@ -10059,13 +10069,24 @@ bool BfModule::TypeIsSubTypeOf(BfTypeInstance* srcType, BfTypeInstance* wantType
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
checkType = checkType->mBaseType;
|
checkType = checkType->GetImplBaseType();
|
||||||
if ((checkType != NULL) && (checkType->mDefineState < BfTypeDefineState_HasInterfaces))
|
if ((checkType != NULL) && (checkType->mDefineState < BfTypeDefineState_HasInterfaces))
|
||||||
{
|
{
|
||||||
PopulateType(checkType, BfPopulateType_Interfaces);
|
PopulateType(checkType, BfPopulateType_Interfaces);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (srcType->IsTypedPrimitive())
|
||||||
|
{
|
||||||
|
BfType* underlyingType = srcType->GetUnderlyingType();
|
||||||
|
if (underlyingType->IsWrappableType())
|
||||||
|
{
|
||||||
|
BfTypeInstance* wrappedType = GetWrappedStructType(underlyingType);
|
||||||
|
if ((wrappedType != NULL) && (wrappedType != srcType))
|
||||||
|
return TypeIsSubTypeOf(wrappedType, wantType, checkAccessibility);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10243,9 +10264,11 @@ void BfModule::DoTypeToString(StringImpl& str, BfType* resolvedType, BfTypeNameF
|
||||||
|
|
||||||
if (resolvedType->IsBoxed())
|
if (resolvedType->IsBoxed())
|
||||||
{
|
{
|
||||||
auto boxedeType = (BfBoxedType*)resolvedType;
|
auto boxedType = (BfBoxedType*)resolvedType;
|
||||||
str += "boxed ";
|
str += "boxed ";
|
||||||
DoTypeToString(str, boxedeType->mElementType, typeNameFlags, genericMethodNameOverrides);
|
DoTypeToString(str, boxedType->mElementType, typeNameFlags, genericMethodNameOverrides);
|
||||||
|
if (boxedType->mBoxedFlags == BfBoxedType::BoxedFlags_StructPtr)
|
||||||
|
str += "*";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if ((resolvedType->IsArray()) && ((typeNameFlags & BfTypeNameFlag_UseArrayImplType) == 0))
|
else if ((resolvedType->IsArray()) && ((typeNameFlags & BfTypeNameFlag_UseArrayImplType) == 0))
|
||||||
|
|
|
@ -1087,6 +1087,7 @@ BfMethodInstanceGroup::~BfMethodInstanceGroup()
|
||||||
|
|
||||||
BfTypeInstance::~BfTypeInstance()
|
BfTypeInstance::~BfTypeInstance()
|
||||||
{
|
{
|
||||||
|
delete mTypeInfoEx;
|
||||||
delete mCustomAttributes;
|
delete mCustomAttributes;
|
||||||
delete mAttributeData;
|
delete mAttributeData;
|
||||||
for (auto methodInst : mInternalMethods)
|
for (auto methodInst : mInternalMethods)
|
||||||
|
@ -1622,17 +1623,25 @@ BfType* BfTypeInstance::GetUnderlyingType()
|
||||||
if (!mIsTypedPrimitive)
|
if (!mIsTypedPrimitive)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
if (mTypeInfoEx == NULL)
|
||||||
|
mTypeInfoEx = new BfTypeInfoEx();
|
||||||
|
if (mTypeInfoEx->mUnderlyingType != NULL)
|
||||||
|
return mTypeInfoEx->mUnderlyingType;
|
||||||
|
|
||||||
auto checkTypeInst = this;
|
auto checkTypeInst = this;
|
||||||
while (checkTypeInst != NULL)
|
while (checkTypeInst != NULL)
|
||||||
{
|
{
|
||||||
if (!checkTypeInst->mFieldInstances.empty())
|
if (!checkTypeInst->mFieldInstances.empty())
|
||||||
return checkTypeInst->mFieldInstances.back().mResolvedType;
|
{
|
||||||
|
mTypeInfoEx->mUnderlyingType = checkTypeInst->mFieldInstances.back().mResolvedType;
|
||||||
|
return mTypeInfoEx->mUnderlyingType;
|
||||||
|
}
|
||||||
checkTypeInst = checkTypeInst->mBaseType;
|
checkTypeInst = checkTypeInst->mBaseType;
|
||||||
if (checkTypeInst->IsIncomplete())
|
if (checkTypeInst->IsIncomplete())
|
||||||
mModule->PopulateType(checkTypeInst, BfPopulateType_Data);
|
mModule->PopulateType(checkTypeInst, BfPopulateType_Data);
|
||||||
}
|
}
|
||||||
BF_FATAL("Failed");
|
BF_FATAL("Failed");
|
||||||
return NULL;
|
return mTypeInfoEx->mUnderlyingType;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BfTypeInstance::IsValuelessType()
|
bool BfTypeInstance::IsValuelessType()
|
||||||
|
@ -1857,6 +1866,15 @@ void BfTupleType::Finish()
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
BfType* BfBoxedType::GetModifiedElementType()
|
||||||
|
{
|
||||||
|
if ((mBoxedFlags & BoxedFlags_StructPtr) != 0)
|
||||||
|
return mModule->CreatePointerType(mElementType);
|
||||||
|
return mElementType;
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
int BfArrayType::GetLengthBitCount()
|
int BfArrayType::GetLengthBitCount()
|
||||||
{
|
{
|
||||||
if (mBaseType == NULL)
|
if (mBaseType == NULL)
|
||||||
|
@ -2461,11 +2479,6 @@ int BfResolvedTypeSet::Hash(BfTypeReference* typeRef, LookupContext* ctx, BfHash
|
||||||
hashVal = ((hashVal ^ (Hash(nullableType->mElementType, ctx))) << 5) - hashVal;
|
hashVal = ((hashVal ^ (Hash(nullableType->mElementType, ctx))) << 5) - hashVal;
|
||||||
return hashVal;
|
return hashVal;
|
||||||
}
|
}
|
||||||
else if (auto boxedType = BfNodeDynCastExact<BfBoxedTypeRef>(typeRef))
|
|
||||||
{
|
|
||||||
int elemHash = Hash(boxedType->mElementType, ctx) ^ HASH_VAL_BOXED;
|
|
||||||
return (elemHash << 5) - elemHash;
|
|
||||||
}
|
|
||||||
else if (auto refType = BfNodeDynCastExact<BfRefTypeRef>(typeRef))
|
else if (auto refType = BfNodeDynCastExact<BfRefTypeRef>(typeRef))
|
||||||
{
|
{
|
||||||
if ((flags & BfHashFlag_AllowRef) != 0)
|
if ((flags & BfHashFlag_AllowRef) != 0)
|
||||||
|
@ -2654,8 +2667,10 @@ bool BfResolvedTypeSet::Equals(BfType* lhs, BfType* rhs, LookupContext* ctx)
|
||||||
{
|
{
|
||||||
if (!rhs->IsBoxed())
|
if (!rhs->IsBoxed())
|
||||||
return false;
|
return false;
|
||||||
BfBoxedType* lhsBoxedType = (BfBoxedType*) lhs;
|
BfBoxedType* lhsBoxedType = (BfBoxedType*)lhs;
|
||||||
BfBoxedType* rhsBoxedType = (BfBoxedType*) rhs;
|
BfBoxedType* rhsBoxedType = (BfBoxedType*)rhs;
|
||||||
|
if (lhsBoxedType->mBoxedFlags != rhsBoxedType->mBoxedFlags)
|
||||||
|
return false;
|
||||||
return Equals(lhsBoxedType->mElementType, rhsBoxedType->mElementType, ctx);
|
return Equals(lhsBoxedType->mElementType, rhsBoxedType->mElementType, ctx);
|
||||||
}
|
}
|
||||||
else if (lhs->IsArray())
|
else if (lhs->IsArray())
|
||||||
|
@ -3050,11 +3065,7 @@ bool BfResolvedTypeSet::Equals(BfType* lhs, BfTypeReference* rhs, LookupContext*
|
||||||
|
|
||||||
if (lhs->IsBoxed())
|
if (lhs->IsBoxed())
|
||||||
{
|
{
|
||||||
auto rhsBoxedTypeRef = BfNodeDynCastExact<BfBoxedTypeRef>(rhs);
|
|
||||||
if (rhsBoxedTypeRef == NULL)
|
|
||||||
return false;
|
return false;
|
||||||
BfBoxedType* lhsBoxedType = (BfBoxedType*) lhs;
|
|
||||||
return Equals(lhsBoxedType->mElementType, rhsBoxedTypeRef->mElementType, ctx);
|
|
||||||
}
|
}
|
||||||
else if (lhs->IsArray())
|
else if (lhs->IsArray())
|
||||||
{
|
{
|
||||||
|
@ -3701,8 +3712,6 @@ String BfTypeUtils::TypeToString(BfTypeReference* typeRef)
|
||||||
|
|
||||||
if (auto ptrType = BfNodeDynCast<BfPointerTypeRef>(typeRef))
|
if (auto ptrType = BfNodeDynCast<BfPointerTypeRef>(typeRef))
|
||||||
return TypeToString(ptrType->mElementType) + "*";
|
return TypeToString(ptrType->mElementType) + "*";
|
||||||
if (auto boxedType = BfNodeDynCast<BfBoxedTypeRef>(typeRef))
|
|
||||||
return "boxed " + TypeToString(boxedType->mElementType);
|
|
||||||
if (auto ptrType = BfNodeDynCast<BfArrayTypeRef>(typeRef))
|
if (auto ptrType = BfNodeDynCast<BfArrayTypeRef>(typeRef))
|
||||||
{
|
{
|
||||||
String name = TypeToString(ptrType->mElementType) + "[";
|
String name = TypeToString(ptrType->mElementType) + "[";
|
||||||
|
|
|
@ -450,6 +450,7 @@ public:
|
||||||
virtual bool IsTypedPrimitive() { return false; }
|
virtual bool IsTypedPrimitive() { return false; }
|
||||||
virtual bool IsComposite() { return IsStruct(); }
|
virtual bool IsComposite() { return IsStruct(); }
|
||||||
virtual bool IsStruct() { return false; }
|
virtual bool IsStruct() { return false; }
|
||||||
|
virtual bool IsStructPtr() { return false; }
|
||||||
virtual bool IsUnion() { return false; }
|
virtual bool IsUnion() { return false; }
|
||||||
virtual bool IsStructOrStructPtr() { return false; }
|
virtual bool IsStructOrStructPtr() { return false; }
|
||||||
virtual bool IsObject() { return false; }
|
virtual bool IsObject() { return false; }
|
||||||
|
@ -494,6 +495,7 @@ public:
|
||||||
virtual bool WantsGCMarking() { return false; }
|
virtual bool WantsGCMarking() { return false; }
|
||||||
virtual BfTypeCode GetLoweredType() { return BfTypeCode_None; }
|
virtual BfTypeCode GetLoweredType() { return BfTypeCode_None; }
|
||||||
virtual BfType* GetUnderlyingType() { return NULL; }
|
virtual BfType* GetUnderlyingType() { return NULL; }
|
||||||
|
virtual bool HasWrappedRepresentation() { return IsWrappableType(); }
|
||||||
virtual bool IsTypeMemberIncluded(BfTypeDef* declaringTypeDef, BfTypeDef* activeTypeDef = NULL, BfModule* module = NULL) { return true; } // May be 'false' only for generic extensions with constraints
|
virtual bool IsTypeMemberIncluded(BfTypeDef* declaringTypeDef, BfTypeDef* activeTypeDef = NULL, BfModule* module = NULL) { return true; } // May be 'false' only for generic extensions with constraints
|
||||||
virtual bool IsTypeMemberAccessible(BfTypeDef* declaringTypeDef, BfTypeDef* activeTypeDef) { return true; }
|
virtual bool IsTypeMemberAccessible(BfTypeDef* declaringTypeDef, BfTypeDef* activeTypeDef) { return true; }
|
||||||
virtual bool IsTypeMemberAccessible(BfTypeDef* declaringTypeDef, BfProject* curProject) { return true; }
|
virtual bool IsTypeMemberAccessible(BfTypeDef* declaringTypeDef, BfProject* curProject) { return true; }
|
||||||
|
@ -1451,6 +1453,21 @@ public:
|
||||||
Array<BfTypeInstance*> mStaticTypes;
|
Array<BfTypeInstance*> mStaticTypes;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class BfTypeInfoEx
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
BfType* mUnderlyingType;
|
||||||
|
int64 mMinValue;
|
||||||
|
int64 mMaxValue;
|
||||||
|
|
||||||
|
BfTypeInfoEx()
|
||||||
|
{
|
||||||
|
mUnderlyingType = NULL;
|
||||||
|
mMinValue = 0;
|
||||||
|
mMaxValue = 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// Instance of struct or class
|
// Instance of struct or class
|
||||||
class BfTypeInstance : public BfDependedType
|
class BfTypeInstance : public BfDependedType
|
||||||
{
|
{
|
||||||
|
@ -1465,6 +1482,7 @@ public:
|
||||||
BfTypeInstance* mBaseType;
|
BfTypeInstance* mBaseType;
|
||||||
BfCustomAttributes* mCustomAttributes;
|
BfCustomAttributes* mCustomAttributes;
|
||||||
BfAttributeData* mAttributeData;
|
BfAttributeData* mAttributeData;
|
||||||
|
BfTypeInfoEx* mTypeInfoEx;
|
||||||
|
|
||||||
Array<BfTypeInterfaceEntry> mInterfaces;
|
Array<BfTypeInterfaceEntry> mInterfaces;
|
||||||
Array<BfTypeInterfaceMethodEntry> mInterfaceMethodTable;
|
Array<BfTypeInterfaceMethodEntry> mInterfaceMethodTable;
|
||||||
|
@ -1528,6 +1546,7 @@ public:
|
||||||
mBaseType = NULL;
|
mBaseType = NULL;
|
||||||
mCustomAttributes = NULL;
|
mCustomAttributes = NULL;
|
||||||
mAttributeData = NULL;
|
mAttributeData = NULL;
|
||||||
|
mTypeInfoEx = NULL;
|
||||||
//mClassVData = NULL;
|
//mClassVData = NULL;
|
||||||
mVirtualMethodTableSize = 0;
|
mVirtualMethodTableSize = 0;
|
||||||
mHotTypeData = NULL;
|
mHotTypeData = NULL;
|
||||||
|
@ -1566,6 +1585,7 @@ public:
|
||||||
virtual BfTypeInstance* ToTypeInstance() override { return this; }
|
virtual BfTypeInstance* ToTypeInstance() override { return this; }
|
||||||
virtual bool IsDependentOnUnderlyingType() override { return true; }
|
virtual bool IsDependentOnUnderlyingType() override { return true; }
|
||||||
virtual BfPrimitiveType* ToPrimitiveType() override { return GetUnderlyingType()->ToPrimitiveType(); }
|
virtual BfPrimitiveType* ToPrimitiveType() override { return GetUnderlyingType()->ToPrimitiveType(); }
|
||||||
|
virtual bool HasWrappedRepresentation() { return IsTypedPrimitive(); }
|
||||||
|
|
||||||
int GetEndingInstanceAlignment() { if (mInstSize % mInstAlign == 0) return mInstAlign; return mInstSize % mInstAlign; }
|
int GetEndingInstanceAlignment() { if (mInstSize % mInstAlign == 0) return mInstAlign; return mInstSize % mInstAlign; }
|
||||||
virtual bool HasTypeFailed() override { return mTypeFailed; }
|
virtual bool HasTypeFailed() override { return mTypeFailed; }
|
||||||
|
@ -1602,6 +1622,8 @@ public:
|
||||||
virtual bool WantsGCMarking() override;
|
virtual bool WantsGCMarking() override;
|
||||||
virtual BfTypeCode GetLoweredType() override;
|
virtual BfTypeCode GetLoweredType() override;
|
||||||
|
|
||||||
|
virtual BfTypeInstance* GetImplBaseType() { return mBaseType; }
|
||||||
|
|
||||||
virtual bool IsIRFuncUsed(BfIRFunction func);
|
virtual bool IsIRFuncUsed(BfIRFunction func);
|
||||||
|
|
||||||
void CalcHotVirtualData(/*Val128& vtHash, */Array<int>* ifaceMapping);
|
void CalcHotVirtualData(/*Val128& vtHash, */Array<int>* ifaceMapping);
|
||||||
|
@ -1626,9 +1648,25 @@ public:
|
||||||
class BfBoxedType : public BfTypeInstance
|
class BfBoxedType : public BfTypeInstance
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
BfTypeInstance* mElementType;
|
enum BoxedFlags
|
||||||
|
{
|
||||||
|
BoxedFlags_None = 0,
|
||||||
|
BoxedFlags_StructPtr = 1
|
||||||
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
BfTypeInstance* mElementType;
|
||||||
|
BfBoxedType* mBoxedBaseType;
|
||||||
|
BoxedFlags mBoxedFlags;
|
||||||
|
|
||||||
|
public:
|
||||||
|
BfBoxedType()
|
||||||
|
{
|
||||||
|
mElementType = NULL;
|
||||||
|
mBoxedBaseType = NULL;
|
||||||
|
mBoxedFlags = BoxedFlags_None;
|
||||||
|
}
|
||||||
|
|
||||||
virtual bool IsBoxed() override { return true; }
|
virtual bool IsBoxed() override { return true; }
|
||||||
|
|
||||||
virtual bool IsValueType() override { return false; }
|
virtual bool IsValueType() override { return false; }
|
||||||
|
@ -1645,6 +1683,15 @@ public:
|
||||||
virtual bool IsSpecializedType() override { return !mElementType->IsUnspecializedType(); }
|
virtual bool IsSpecializedType() override { return !mElementType->IsUnspecializedType(); }
|
||||||
virtual bool IsUnspecializedType() override { return mElementType->IsUnspecializedType(); }
|
virtual bool IsUnspecializedType() override { return mElementType->IsUnspecializedType(); }
|
||||||
virtual bool IsUnspecializedTypeVariation() override { return mElementType->IsUnspecializedTypeVariation(); }
|
virtual bool IsUnspecializedTypeVariation() override { return mElementType->IsUnspecializedTypeVariation(); }
|
||||||
|
|
||||||
|
virtual BfTypeInstance* GetImplBaseType() { return (mBoxedBaseType != NULL) ? mBoxedBaseType : mBaseType; }
|
||||||
|
|
||||||
|
bool IsBoxedStructPtr()
|
||||||
|
{
|
||||||
|
return (mBoxedFlags & BoxedFlags_StructPtr) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
BfType* GetModifiedElementType();
|
||||||
};
|
};
|
||||||
|
|
||||||
class BfGenericExtensionEntry
|
class BfGenericExtensionEntry
|
||||||
|
@ -1862,6 +1909,7 @@ public:
|
||||||
virtual bool IsReified() { return mElementType->IsReified(); }
|
virtual bool IsReified() { return mElementType->IsReified(); }
|
||||||
virtual bool IsPointer() override { return true; }
|
virtual bool IsPointer() override { return true; }
|
||||||
virtual bool IsIntPtrable() override { return true; }
|
virtual bool IsIntPtrable() override { return true; }
|
||||||
|
virtual bool IsStructPtr() override { return mElementType->IsStruct(); }
|
||||||
virtual bool IsStructOrStructPtr() override { return mElementType->IsStruct(); }
|
virtual bool IsStructOrStructPtr() override { return mElementType->IsStruct(); }
|
||||||
virtual bool IsValueTypeOrValueTypePtr() override { return mElementType->IsValueType(); }
|
virtual bool IsValueTypeOrValueTypePtr() override { return mElementType->IsValueType(); }
|
||||||
virtual bool IsDependentOnUnderlyingType() override { return true; }
|
virtual bool IsDependentOnUnderlyingType() override { return true; }
|
||||||
|
@ -2174,7 +2222,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
mCount++;
|
mCount++;
|
||||||
Entry* entry = new Entry();
|
Entry* entry = (Entry*)BfResolvedTypeSetFuncs::Allocate(sizeof(Entry), alignof(Entry));
|
||||||
entry->mValue = NULL;
|
entry->mValue = NULL;
|
||||||
// if (mHashHeads[bucket] != NULL)
|
// if (mHashHeads[bucket] != NULL)
|
||||||
// mHashHeads[bucket]->mPrev = entry;
|
// mHashHeads[bucket]->mPrev = entry;
|
||||||
|
|
|
@ -582,25 +582,7 @@ BOOL WINAPI DllMain(
|
||||||
DWORD dwReason,
|
DWORD dwReason,
|
||||||
LPVOID lpreserved)
|
LPVOID lpreserved)
|
||||||
{
|
{
|
||||||
//::MessageBoxA(NULL, "A", "B", MB_OK);
|
|
||||||
|
|
||||||
// MemReporter memReporter;
|
|
||||||
// memReporter.mShowInKB = false;
|
|
||||||
// {
|
|
||||||
// memReporter.BeginSection("A");
|
|
||||||
// {
|
|
||||||
// memReporter.BeginSection("B");
|
|
||||||
// memReporter.Add(10);
|
|
||||||
//
|
|
||||||
// memReporter.Add("C", 1);
|
|
||||||
// memReporter.Add("D", 2);
|
|
||||||
//
|
|
||||||
// memReporter.EndSection();
|
|
||||||
// }
|
|
||||||
// memReporter.EndSection();
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// memReporter.Report();
|
|
||||||
|
|
||||||
if (dwReason == DLL_PROCESS_ATTACH)
|
if (dwReason == DLL_PROCESS_ATTACH)
|
||||||
{
|
{
|
||||||
|
@ -641,57 +623,9 @@ static _CrtMemState gStartMemCheckpoint;
|
||||||
#endif
|
#endif
|
||||||
BF_EXPORT void BF_CALLTYPE Debugger_Create()
|
BF_EXPORT void BF_CALLTYPE Debugger_Create()
|
||||||
{
|
{
|
||||||
String outStr = BfDemangler::Demangle(
|
|
||||||
"??0?$_String_alloc@U?$_String_base_types@DV?$allocator@D@std@@@std@@@std@@QEAA@AEBV?$allocator@D@1@@Z"
|
|
||||||
//"?_Tidy@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAAX_N_K@Z"
|
|
||||||
//"?gamma@Class1@@2PAY04NA"
|
|
||||||
//"?alpha@@3HA"
|
|
||||||
//"?Fis_i@myclass@@SAHH@Z"
|
|
||||||
//"??$?0AEBV?$allocator@D@std@@$$V@?$_Compressed_pair@U?$_Wrap_alloc@V?$allocator@D@std@@@std@@V?$_String_val@U?$_Simple_types@D@std@@@2@$00@std@@QEAA@U_One_then_variadic_args_t@1@AEBV?$allocator@D@1@@Z"
|
|
||||||
|
|
||||||
//"??0?$map@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@IU?$less@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@2@V?$allocator@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@I@std@@@2@@std@@QEAA@XZ"
|
|
||||||
//"??4?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAAAEAV01@PEBD@Z"
|
|
||||||
//"??0?$allocator@_W@std@@QEAA@XZ"
|
|
||||||
//"??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAA@XZ"
|
|
||||||
, DbgLanguage_C);
|
|
||||||
|
|
||||||
/*{
|
|
||||||
|
|
||||||
struct TestStruct
|
|
||||||
{
|
|
||||||
TestStruct* mNext;
|
|
||||||
int mInt;
|
|
||||||
|
|
||||||
TestStruct(int i)
|
|
||||||
{
|
|
||||||
mNext = NULL;
|
|
||||||
mInt = i;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
TestStruct tsArr[5] = { 1, 2, 3, 4, 5 };
|
|
||||||
SLIList<TestStruct*> sliList;
|
|
||||||
|
|
||||||
sliList.PushBack(&tsArr[0]);
|
|
||||||
//sliList.PushBack(&tsArr[1]);
|
|
||||||
//sliList.PushBack(&tsArr[2]);
|
|
||||||
|
|
||||||
auto itr = sliList.begin();
|
|
||||||
auto* val = *itr;
|
|
||||||
//++itr;
|
|
||||||
//val = *itr;
|
|
||||||
//++itr;
|
|
||||||
//val = *itr;
|
|
||||||
sliList.erase(itr);
|
|
||||||
bool isEnd = itr == sliList.end();
|
|
||||||
}*/
|
|
||||||
|
|
||||||
String str = StrFormat("%d:%@:%l@", 123, (intptr)0x1234567890LL, 0xABCDEF7890LL);
|
|
||||||
//String str = StrFormat("%l@", "Yo");
|
|
||||||
|
|
||||||
//TODO: Very slow, remove
|
//TODO: Very slow, remove
|
||||||
//_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_CHECK_ALWAYS_DF);
|
//_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_CHECK_ALWAYS_DF);
|
||||||
|
//_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_CHECK_EVERY_16_DF);
|
||||||
//TODO: _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF /*| _CRTDBG_CHECK_EVERY_16_DF*/);
|
//TODO: _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF /*| _CRTDBG_CHECK_EVERY_16_DF*/);
|
||||||
//_CrtSetAllocHook(BfAllocHook);
|
//_CrtSetAllocHook(BfAllocHook);
|
||||||
|
|
||||||
|
|
|
@ -9,10 +9,9 @@ namespace Tests
|
||||||
int Get() mut;
|
int Get() mut;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Struct : IFace
|
struct StructA : IFace
|
||||||
{
|
{
|
||||||
public int mA = 100;
|
public int mA = 100;
|
||||||
public int mB = 200;
|
|
||||||
|
|
||||||
public int Get() mut
|
public int Get() mut
|
||||||
{
|
{
|
||||||
|
@ -21,20 +20,87 @@ namespace Tests
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct StructB : StructA, IHashable
|
||||||
|
{
|
||||||
|
public int mB = 200;
|
||||||
|
|
||||||
|
public int GetHashCode()
|
||||||
|
{
|
||||||
|
return mB;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct StructC : StructB
|
||||||
|
{
|
||||||
|
public int mC = 300;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int GetFromIFace<T>(mut T val) where T : IFace
|
||||||
|
{
|
||||||
|
return val.Get();
|
||||||
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public static void TestBasics()
|
public static void TestBasics()
|
||||||
{
|
{
|
||||||
Struct val0 = .();
|
StructA valA = .();
|
||||||
Object obj0 = val0;
|
Object obj0 = valA;
|
||||||
IFace iface0 = (IFace)obj0;
|
IFace iface0 = (IFace)obj0;
|
||||||
|
Test.Assert(GetFromIFace(mut valA) == 1100);
|
||||||
Test.Assert(iface0.Get() == 1100);
|
Test.Assert(iface0.Get() == 1100);
|
||||||
Test.Assert(val0.mA == 100); // This should copy values
|
Test.Assert(GetFromIFace(iface0) == 2100);
|
||||||
|
Test.Assert(valA.mA == 1100); // This should copy values
|
||||||
|
|
||||||
/*Struct val1 = .();
|
StructB valB = .();
|
||||||
Object obj1 = (Object)(ref val1);
|
IFace iface1 = valB;
|
||||||
IFace iface1 = (IFace)obj1;
|
Test.Assert(GetFromIFace(mut valB) == 1100);
|
||||||
Test.Assert(iface1.Get() == 1100);
|
Test.Assert(iface1.Get() == 1100);
|
||||||
Test.Assert(val1.mA == 1100); // This should reference values*/
|
Test.Assert(GetFromIFace(iface1) == 2100);
|
||||||
|
Test.Assert(valB.mA == 1100); // This should copy values
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public static void TestPtr()
|
||||||
|
{
|
||||||
|
StructA* valA = scope .();
|
||||||
|
Object obj0 = valA;
|
||||||
|
IFace iface0 = (IFace)obj0;
|
||||||
|
Test.Assert(GetFromIFace(mut valA) == 1100);
|
||||||
|
Test.Assert(iface0.Get() == 2100);
|
||||||
|
Test.Assert(GetFromIFace(iface0) == 3100);
|
||||||
|
Test.Assert(valA.mA == 3100); // This should copy values
|
||||||
|
|
||||||
|
StructB* valB = scope .();
|
||||||
|
IFace iface1 = valB;
|
||||||
|
Test.Assert(GetFromIFace(mut valB) == 1100);
|
||||||
|
Test.Assert(iface1.Get() == 2100);
|
||||||
|
Test.Assert(GetFromIFace(iface1) == 3100);
|
||||||
|
Test.Assert(valB.mA == 3100); // This should copy values
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int GetHash<T>(T val) where T : IHashable
|
||||||
|
{
|
||||||
|
return val.GetHashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public static void TestPtrHash()
|
||||||
|
{
|
||||||
|
StructA* valA = scope .();
|
||||||
|
StructB* valB = scope .();
|
||||||
|
StructC* valC = scope .();
|
||||||
|
|
||||||
|
IHashable ihA = valA;
|
||||||
|
IHashable ihB = valB;
|
||||||
|
IHashable ihC = valC;
|
||||||
|
|
||||||
|
Test.Assert(ihA.GetHashCode() == (int)valA);
|
||||||
|
Test.Assert(ihB.GetHashCode() == (int)valB);
|
||||||
|
Test.Assert(ihC.GetHashCode() == (int)valC);
|
||||||
|
|
||||||
|
Test.Assert(GetHash(ihA) == (int)valA);
|
||||||
|
Test.Assert(GetHash(ihB) == (int)valB);
|
||||||
|
Test.Assert(GetHash(ihC) == (int)valC);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue