1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-08 11:38:21 +02:00

Boxed struct ptr changes.

This commit is contained in:
Brian Fiete 2019-10-09 16:16:01 -07:00
parent ad2542eba6
commit 5af6428bf4
20 changed files with 573 additions and 327 deletions

View file

@ -1,12 +1,29 @@
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;
public int GetHashCode()
{
return (int)mVal;
}
}
}

View file

@ -154,6 +154,14 @@ namespace System.Reflection
Type underlyingType = argType.UnderlyingType;
if ((paramType.IsPrimitive) && (underlyingType.IsTypedPrimitive)) // Boxed primitive?
underlyingType = underlyingType.UnderlyingType;
if (argType.IsBoxedStructPtr)
{
dataPtr = *(void**)dataPtr;
handled = true;
}
else
{
if (!underlyingType.IsSubtypeOf(paramType))
{
if (underlyingType.IsGenericType)
@ -175,6 +183,7 @@ namespace System.Reflection
}*/
}
}
if (!handled)
{

View file

@ -213,6 +213,14 @@ namespace System
}
}
public bool IsPointer
{
get
{
return (mTypeFlags & (TypeFlags.Boxed | TypeFlags.Pointer)) == TypeFlags.Pointer;
}
}
public bool IsBoxed
{
get
@ -221,6 +229,14 @@ namespace System
}
}
public bool IsBoxedStructPtr
{
get
{
return (mTypeFlags & (TypeFlags.Boxed | TypeFlags.Pointer)) == TypeFlags.Boxed | TypeFlags.Pointer;
}
}
public bool IsEnum
{
get

View file

@ -1358,12 +1358,11 @@ void BeIRCodeGen::HandleNextCmd()
CMD_PARAM(BeValue*, val);
CMD_PARAM(int, idx);
BF_ASSERT(val->GetType()->IsComposite());
auto extractValueInst = mBeModule->AllocInst<BeExtractValueInst>();
extractValueInst->mAggVal = val;
extractValueInst->mIdx = idx;
BF_ASSERT(val->GetType()->IsComposite());
SetResult(curId, extractValueInst);
}
break;

View file

@ -2394,6 +2394,20 @@ void BeModule::Print(BeFunction* 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)
{
//bool debugging = func->mName == "?Test@Program@bf@@CAXXZ";
@ -3139,8 +3153,8 @@ BeGEPInst* BeModule::CreateGEP(BeValue* ptr, BeValue* idx0, BeValue* idx1)
inst->mIdx1 = idx1;
AddInst(inst);
BF_ASSERT(ptr->GetType()->IsPointer());
#ifdef _DEBUG
BF_ASSERT(ptr->GetType()->IsPointer());
inst->GetType();
#endif

View file

@ -2109,6 +2109,7 @@ public:
String ToString(BeFunction* func = NULL);
void Print();
void Print(BeFunction* func);
void PrintValue(BeValue* val);
void DoInlining(BeFunction* func);
void DoInlining();

View file

@ -2427,12 +2427,6 @@ public:
BfTokenNode* mRefToken;
}; BF_AST_DECL(BfRefTypeRef, BfElementedTypeRef);
class BfBoxedTypeRef : public BfElementedTypeRef
{
public:
BF_AST_TYPE(BfBoxedTypeRef, BfElementedTypeRef);
}; BF_AST_DECL(BfBoxedTypeRef, BfElementedTypeRef);
class BfParamsExpression : public BfExpression
{
public:

View file

@ -1394,7 +1394,7 @@ void BfAutoComplete::CheckIdentifier(BfIdentifierNode* identifierNode, bool isIn
"delegate", "extern", "enum", "explicit", "extension", "function",
"interface", "in", "internal", "mixin", "namespace", "new",
"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"
};
for (int i = 0; i < sizeof(tokens)/sizeof(char*); i++)

View file

@ -397,6 +397,7 @@ BfCompiler::BfCompiler(BfSystem* bfSystem, bool isResolveOnly)
mInlineAttributeTypeDef = NULL;
mInternalTypeDef = NULL;
mIPrintableTypeDef = NULL;
mIHashableTypeDef = NULL;
mLinkNameAttributeTypeDef = NULL;
mMethodRefTypeDef = NULL;
mNullableTypeDef = NULL;
@ -422,6 +423,9 @@ BfCompiler::BfCompiler(BfSystem* bfSystem, bool isResolveOnly)
mTypeTypeDef = NULL;
mUnboundAttributeTypeDef = NULL;
mValueTypeTypeDef = NULL;
mObsoleteAttributeTypeDef = NULL;
mErrorAttributeTypeDef = NULL;
mWarnAttributeTypeDef = NULL;
mLastAutocompleteModule = NULL;
}
@ -4826,6 +4830,9 @@ void BfCompiler::PopulateReified()
void BfCompiler::HotCommit()
{
if (mHotState == NULL)
return;
mHotState->mCommittedHotCompileIdx = mOptions.mHotCompileIdx;
for (auto type : mContext->mResolvedTypes)
@ -5808,6 +5815,7 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory)
mInlineAttributeTypeDef = _GetRequiredType("System.InlineAttribute");
mInternalTypeDef = _GetRequiredType("System.Internal");
mIPrintableTypeDef = _GetRequiredType("System.IPrintable");
mIHashableTypeDef = _GetRequiredType("System.IHashable");
mLinkNameAttributeTypeDef = _GetRequiredType("System.LinkNameAttribute");
mMethodRefTypeDef = _GetRequiredType("System.MethodReference", 1);
mNullableTypeDef = _GetRequiredType("System.Nullable");
@ -5834,6 +5842,9 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory)
mTypeTypeDef = _GetRequiredType("System.Type");
mUnboundAttributeTypeDef = _GetRequiredType("System.UnboundAttribute");
mValueTypeTypeDef = _GetRequiredType("System.ValueType");
mObsoleteAttributeTypeDef = _GetRequiredType("System.ObsoleteAttribute");
mErrorAttributeTypeDef = _GetRequiredType("System.ErrorAttribute");
mWarnAttributeTypeDef = _GetRequiredType("System.WarnAttribute");
for (int i = 0; i < BfTypeCode_Length; i++)
mContext->mPrimitiveStructTypes[i] = NULL;

View file

@ -325,33 +325,30 @@ public:
BfTypeDef* mArray3TypeDef;
BfTypeDef* mArray4TypeDef;
BfTypeDef* mSpanTypeDef;
BfTypeDef* mAttributeTypeDef;
BfTypeDef* mAttributeUsageAttributeTypeDef;
BfTypeDef* mBfObjectTypeDef;
BfTypeDef* mClassVDataTypeDef;
BfTypeDef* mCLinkAttributeTypeDef;
BfTypeDef* mCReprAttributeTypeDef;
BfTypeDef* mNoDiscardAttributeTypeDef;
BfTypeDef* mDisableObjectAccessChecksAttributeTypeDef;
BfTypeDef* mDbgRawAllocDataTypeDef;
BfTypeDef* mDeferredCallTypeDef;
BfTypeDef* mDelegateTypeDef;
BfTypeDef* mEnumTypeDef;
BfTypeDef* mFriendAttributeTypeDef;
BfTypeDef* mCheckedAttributeTypeDef;
BfTypeDef* mUncheckedAttributeTypeDef;
BfTypeDef* mStringTypeDef;
BfTypeDef* mTypeTypeDef;
BfTypeDef* mValueTypeTypeDef;
BfTypeDef* mFunctionTypeDef;
BfTypeDef* mGCTypeDef;
BfTypeDef* mGenericIEnumerableTypeDef;
BfTypeDef* mGenericIEnumeratorTypeDef;
BfTypeDef* mGenericIRefEnumeratorTypeDef;
BfTypeDef* mInlineAttributeTypeDef;
BfTypeDef* mInternalTypeDef;
BfTypeDef* mIPrintableTypeDef;
BfTypeDef* mLinkNameAttributeTypeDef;
BfTypeDef* mIHashableTypeDef;
BfTypeDef* mMethodRefTypeDef;
BfTypeDef* mNullableTypeDef;
BfTypeDef* mOrderedAttributeTypeDef;
BfTypeDef* mPointerTTypeDef;
BfTypeDef* mPointerTypeDef;
BfTypeDef* mReflectArrayType;
@ -364,16 +361,30 @@ public:
BfTypeDef* mReflectSpecializedGenericType;
BfTypeDef* mReflectTypeInstanceTypeDef;
BfTypeDef* mReflectUnspecializedGenericType;
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* mStaticInitAfterAttributeTypeDef;
BfTypeDef* mStaticInitPriorityAttributeTypeDef;
BfTypeDef* mStringTypeDef;
BfTypeDef* mTestAttributeTypeDef;
BfTypeDef* mThreadStaticAttributeTypeDef;
BfTypeDef* mTypeTypeDef;
BfTypeDef* mUnboundAttributeTypeDef;
BfTypeDef* mValueTypeTypeDef;
BfTypeDef* mObsoleteAttributeTypeDef;
BfTypeDef* mErrorAttributeTypeDef;
BfTypeDef* mWarnAttributeTypeDef;
int mCurTypeId;
int mTypeInitCount;

View file

@ -88,6 +88,7 @@ BfContext::~BfContext()
int numTypesDeleted = 0;
for (auto type : mResolvedTypes)
{
//_CrtCheckMemory();
delete type;
}
@ -930,6 +931,11 @@ void BfContext::RebuildType(BfType* type, bool deleteOnDemandTypes, bool rebuild
typeInst->mIsSplattable = false;
typeInst->mHasPackingHoles = false;
typeInst->mWantsGCMarking = false;
if (typeInst->mTypeInfoEx != NULL)
{
delete typeInst->mTypeInfoEx;
typeInst->mTypeInfoEx = NULL;
}
if (typeInst->IsGenericTypeInstance())
{
@ -2082,6 +2088,9 @@ void BfContext::GenerateModuleName_Type(BfType* type, String& name)
if (type->IsBoxed())
{
auto boxedType = (BfBoxedType*)type;
if (boxedType->IsBoxedStructPtr())
name += "BOXPTR_";
else
name += "BOX_";
GenerateModuleName_Type(boxedType->mElementType, name);
return;

View file

@ -1730,6 +1730,8 @@ String BfIRBuilder::GetDebugTypeName(BfTypeInstance* typeInstance, bool includeO
{
BfBoxedType* boxedType = (BfBoxedType*)typeInstance;
typeName = mModule->TypeToString(boxedType->mElementType, (BfTypeNameFlags)(BfTypeNameFlag_ResolveGenericParamNames | BfTypeNameFlag_AddGlobalContainerName));
if (boxedType->IsBoxedStructPtr())
typeName += "*";
typeName = "Box<" + typeName + ">";
}
else if (includeOuterTypeName)
@ -2547,7 +2549,7 @@ void BfIRBuilder::CreateDbgTypeDefinition(BfType* type)
}
else if (type->IsBoxed())
{
auto underlyingType = typeInstance->GetUnderlyingType();
auto underlyingType = ((BfBoxedType*)type)->GetModifiedElementType();
if (!underlyingType->IsValuelessType())
{
auto fieldInstance = &typeInstance->mFieldInstances.back();
@ -2705,9 +2707,14 @@ void BfIRBuilder::CreateTypeDefinition(BfType* type, bool forceDefine)
if (typeInstance->IsBoxed())
{
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

View file

@ -331,7 +331,7 @@ void BfGNUMangler::MangleTypeInst(MangleContext& mangleContext, StringImpl& name
auto boxedType = (BfBoxedType*)typeInst;
name += "N3BoxI";
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";
mangleContext.mSubstituteList.push_back(NameSubstitute(BfGNUMangler::NameSubstitute::Kind_None, NULL)); // Insert entry for 'Box<T>'
if (isEndOpen != NULL)
@ -1158,7 +1158,7 @@ bool BfMSMangler::FindOrCreateNameSub(MangleContext& mangleContext, StringImpl&
auto boxedType = (BfBoxedType*)newNameSub.mTypeInst;
name += "?$Box@";
BfTypeVector typeVec;
typeVec.push_back(boxedType->mElementType);
typeVec.push_back(boxedType->GetModifiedElementType());
AddGenericArgs(mangleContext, name, typeVec);
name += '@';
}

View file

@ -1130,7 +1130,7 @@ void BfModule::EnsureIRBuilder(bool dbgVerifyCodeGen)
// code as we walk the AST
//mBfIRBuilder->mDbgVerifyCodeGen = true;
if (
(mModuleName == "-")
(mModuleName == "Program")
//|| (mModuleName == "System_Internal")
//|| (mModuleName == "vdata")
//|| (mModuleName == "Hey_Dude_Bro_TestClass")
@ -1583,6 +1583,17 @@ int BfModule::GetStringPoolIdx(BfIRValue constantStr, BfIRConstHolder* constHold
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* irValue = NULL;
@ -4264,10 +4275,6 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
BfTypeInstance* typeInstance = type->ToTypeInstance();
// BfType* typeInstanceType = ResolveTypeDef(mCompiler->mReflectTypeInstanceTypeDef, BfPopulateType_Identity);
// mBfIRBuilder->PopulateType(typeInstanceType, BfIRPopulateType_Full_ForceDefinition);
// PopulateType(typeInstanceType);
BfType* typeInstanceType = ResolveTypeDef(mCompiler->mReflectTypeInstanceTypeDef);
mBfIRBuilder->PopulateType(typeInstanceType, BfIRPopulateType_Full_ForceDefinition);
@ -4379,7 +4386,11 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
if (type->IsStruct())
typeFlags |= BfTypeFlags_Struct;
if (type->IsBoxed())
{
typeFlags |= BfTypeFlags_Boxed;
if (((BfBoxedType*)type)->IsBoxedStructPtr())
typeFlags |= BfTypeFlags_Pointer;
}
if (type->IsPrimitiveType())
typeFlags |= BfTypeFlags_Primitive;
if (type->IsTypedPrimitive())
@ -4573,10 +4584,11 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
{
if (interfaceEntry.mInterfaceType->mSlotNum >= 0)
{
if (dynCastData[interfaceEntry.mInterfaceType->mSlotNum + 1] == 0)
dynCastData[interfaceEntry.mInterfaceType->mSlotNum + 1] = interfaceEntry.mInterfaceType->mTypeId;
}
}
checkTypeInst = checkTypeInst->mBaseType;
checkTypeInst = checkTypeInst->GetImplBaseType();
}
if (mSystem->mPtrSize == 8)
@ -4633,6 +4645,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
Dictionary<BfTypeInstance*, _InterfaceMatchEntry> interfaceMap;
auto checkTypeInst = typeInstance;
bool forceInterfaceSet = false;
while (checkTypeInst != NULL)
{
for (auto&& interfaceEntry : checkTypeInst->mInterfaces)
@ -4648,6 +4661,11 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
auto prevEntry = matchEntry->mEntry;
bool isBetter = TypeIsSubTypeOf(checkTypeInst, matchEntry->mEntrySource);
bool isWorse = TypeIsSubTypeOf(matchEntry->mEntrySource, checkTypeInst);
if (forceInterfaceSet)
{
isBetter = true;
isWorse = false;
}
if (isBetter == isWorse)
CompareDeclTypes(interfaceEntry.mDeclaringType, prevEntry->mDeclaringType, 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)
@ -4701,7 +4719,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
while (checkTypeInst != NULL)
{
origVirtTypeStack.push_back(checkTypeInst);
checkTypeInst = checkTypeInst->mBaseType;
checkTypeInst = checkTypeInst->GetImplBaseType();
}
Array<BfVirtualMethodEntry> origVTable;
@ -4860,14 +4878,6 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
makeEmpty = true;
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;
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);
// This doesn't work because we may have FOREIGN methods from implicit interface methods
//auto moduleMethodInst = GetMethodInstanceAtIdx(methodRef.mTypeInstance, methodRef.mMethodNum);
BfMethodInstance* methodInstance = methodRef;
auto moduleMethodInst = ReferenceExternalMethodInstance(methodInstance);
auto funcPtr = mBfIRBuilder->CreateBitCast(moduleMethodInst.mFunc, voidPtrIRType);
pushValue = funcPtr;
@ -4906,8 +4915,6 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
}
int idx = interfaceEntry->mStartVirtualIdx + ifaceMethodInstance->mVirtualTableIdx;
// if (!useExt)
// vData[iFaceMethodStartIdx + idx] = pushValue;
if (idx < ifaceMethodExtStart)
{
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))
{
BfIRValue ifaceMethodExtVar;
@ -6541,7 +6587,15 @@ bool BfModule::CheckGenericConstraints(const BfGenericParamSource& genericParamS
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()))
{
BfTypeInstance* wrappedStructType = GetWrappedStructType(origCheckArgType, false);
@ -8228,23 +8282,40 @@ BfTypedValue BfModule::BoxValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp
return BfTypedValue(phi, resultType);
}
if (fromStructTypeInstance == NULL)
{
auto primType = (BfPrimitiveType*) typedVal.mType;
fromStructTypeInstance = GetWrappedStructType(typedVal.mType);
}
if (fromStructTypeInstance == NULL)
return BfTypedValue();
bool alreadyCheckedCast = false;
BfTypeInstance* toTypeInstance = NULL;
if (toType != NULL)
toTypeInstance = toType->ToTypeInstance();
// Need to box it
bool isBoxedType = (fromStructTypeInstance != NULL) && (toType->IsBoxed()) && (CreateBoxedType(fromStructTypeInstance) == toType);
if ((toType == NULL) || (toType == mContext->mBfObjectType) || (isBoxedType) || (TypeIsSubTypeOf(fromStructTypeInstance, toTypeInstance)))
bool isStructPtr = typedVal.mType->IsStructPtr();
if (fromStructTypeInstance == NULL)
{
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);
AddDependency(boxedType, mCurTypeInstance, BfDependencyMap::DependencyFlag_ReadFields);
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);
auto valPtr = mBfIRBuilder->CreateInBoundsGEP(allocaInst, 0, 1);
if (typedVal.mType != fromStructTypeInstance)
if ((typedVal.mType != fromStructTypeInstance) && (!isStructPtr))
{
auto ptrType = CreatePointerType(typedVal.mType);
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);
BfTypedValue innerVal(thisValue, innerType, true);
if (boxedType->IsBoxedStructPtr())
{
innerVal = LoadValue(innerVal);
innerVal = BfTypedValue(innerVal.mValue, innerType, true);
}
exprEvaluator.PushThis(NULL, innerVal, innerMethodInstance.mMethodInstance, innerParams);
}

View file

@ -1388,6 +1388,7 @@ public:
BfIRValue CreateStringObjectValue(const StringImpl& str, int stringId, bool define);
BfIRValue CreateStringCharPtr(const StringImpl& str, int stringId, bool define);
int GetStringPoolIdx(BfIRValue constantStr, BfIRConstHolder* constHolder = NULL);
String* GetStringPoolString(BfIRValue constantStr, BfIRConstHolder* constHolder = NULL);
BfIRValue GetStringCharPtr(int stringId);
BfIRValue GetStringCharPtr(BfIRValue strValue);
BfIRValue GetStringCharPtr(const StringImpl& str);

View file

@ -1749,11 +1749,6 @@ bool BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
if (baseType != NULL)
defaultBaseTypeInst = baseType->ToTypeInstance();
if (typeInstance->mTypeId == 260)
{
NOP;
}
BfTypeReference* baseTypeRef = NULL;
if ((typeDef->mIsDelegate) && (!typeInstance->IsClosure()))
{
@ -1902,6 +1897,18 @@ bool BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
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;
}
@ -2097,16 +2104,18 @@ bool BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
if (resolvedTypeRef->IsBoxed())
{
BfBoxedType* boxedType = (BfBoxedType*)resolvedTypeRef;
BfTypeInstance* innerType = boxedType->mElementType->ToTypeInstance();
BfType* innerType = boxedType->mElementType;
if (boxedType->IsBoxedStructPtr())
innerType = CreatePointerType(innerType);
if (innerType->IsIncomplete())
PopulateType(innerType, BfPopulateType_Data);
auto baseType = typeInstance->mBaseType;
dataPos = baseType->mInstSize;
int alignSize = std::max(innerType->mInstAlign, baseType->mInstAlign);
int alignSize = BF_MAX(innerType->mAlign, baseType->mInstAlign);
if (alignSize > 1)
dataPos = (dataPos + (alignSize - 1)) & ~(alignSize - 1);
int dataSize = innerType->mInstSize;
int dataSize = innerType->mSize;
typeInstance->mFieldInstances.push_back(BfFieldInstance());
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);
}
if (underlyingTypeDeferred)
if (typeInstance->IsEnum())
{
int64 min = 0;
int64 max = 0;
bool isFirst = false;
if (typeInstance->mTypeInfoEx == NULL)
typeInstance->mTypeInfoEx = new BfTypeInfoEx();
for (auto& fieldInstanceRef : typeInstance->mFieldInstances)
{
auto fieldInstance = &fieldInstanceRef;
auto fieldDef = fieldInstance->GetFieldDef();
if ((fieldDef != NULL) && (fieldDef->IsEnumCaseEntry()))
{
auto constant = typeInstance->mConstHolder->GetConstantById(fieldInstance->mConstIdx);
BF_ASSERT(constant->mTypeCode == BfTypeCode_Int64);
if (fieldInstance->mConstIdx == -1)
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);
max = BF_MAX(constant->mInt64, max);
}
}
}
typeInstance->mTypeInfoEx->mMinValue = min;
typeInstance->mTypeInfoEx->mMaxValue = max;
if (underlyingTypeDeferred)
{
BfTypeCode typeCode;
if ((min >= -0x80) && (max <= 0x7F))
@ -3001,6 +3032,8 @@ bool BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
fieldInstance->mResolvedType = underlyingType;
fieldInstance->mDataSize = underlyingType->mSize;
typeInstance->mTypeInfoEx->mUnderlyingType = underlyingType;
typeInstance->mSize = underlyingType->mSize;
typeInstance->mAlign = underlyingType->mAlign;
typeInstance->mInstSize = underlyingType->mSize;
@ -3008,6 +3041,11 @@ bool BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
typeInstance->mRebuildFlags = (BfTypeRebuildFlags)(typeInstance->mRebuildFlags & ~BfTypeRebuildFlag_UnderlyingTypeDeferred);
}
}
else
{
BF_ASSERT(!underlyingTypeDeferred);
}
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
// This allows us to properly deleted a dependent generic type if a typeGenericArg gets deleted.
//...
// 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 (typeInstance == mContext->mBfObjectType)
typeInstance->mHasBeenInstantiated = true;
if (populateType == BfPopulateType_Data)
return true;
@ -3181,16 +3194,16 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance)
}
int newIntefaceStartIdx = 0;
auto baseType = typeInstance->mBaseType;
if (baseType != NULL)
auto implBaseType = typeInstance->GetImplBaseType();
if (implBaseType != NULL)
{
auto baseTypeInst = baseType->ToTypeInstance();
if (baseType->IsIncomplete())
PopulateType(baseType, BfPopulateType_Full_Force);
auto baseTypeInst = implBaseType->ToTypeInstance();
if (implBaseType->IsIncomplete())
PopulateType(implBaseType, BfPopulateType_Full_Force);
typeInstance->mInterfaceMethodTable = baseTypeInst->mInterfaceMethodTable;
typeInstance->mVirtualMethodTable = baseType->mVirtualMethodTable;
typeInstance->mVirtualMethodTableSize = baseType->mVirtualMethodTableSize;
typeInstance->mVirtualMethodTable = implBaseType->mVirtualMethodTable;
typeInstance->mVirtualMethodTableSize = implBaseType->mVirtualMethodTableSize;
if ((!mCompiler->IsHotCompile()) && (!mCompiler->mPassInstance->HasFailed()) && ((mCompiler->mResolvePassData == NULL) || (mCompiler->mResolvePassData->mAutoComplete == NULL)))
{
BF_ASSERT(typeInstance->mVirtualMethodTable.size() == typeInstance->mVirtualMethodTableSize);
@ -3231,7 +3244,7 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance)
{
AddDependency(interfaceEntry.mInterfaceType, typeInstance, BfDependencyMap::DependencyFlag_ImplementsInterface);
}
checkTypeInstance = checkTypeInstance->mBaseType;
checkTypeInstance = checkTypeInstance->GetImplBaseType();
}
//for (auto& intefaceInst : typeInstance->mInterfaces)
@ -3241,11 +3254,16 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance)
BF_ASSERT(typeInstance->mInterfaceMethodTable.size() == 1);
}
if (typeInstance->mTypeDef == mCompiler->mPointerTypeDef)
{
NOP;
}
// Slot interfaces method blocks in vtable
{
int ifaceVirtIdx = 0;
std::unordered_map<BfTypeInstance*, BfTypeInterfaceEntry*> interfaceMap;
BfTypeInstance* checkType = typeInstance->mBaseType;
BfTypeInstance* checkType = typeInstance->GetImplBaseType();
while (checkType != NULL)
{
for (auto&& ifaceEntry : checkType->mInterfaces)
@ -3253,7 +3271,7 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance)
interfaceMap[ifaceEntry.mInterfaceType] = &ifaceEntry;
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++)
@ -3279,12 +3297,12 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance)
typeInstance->mNeedsMethodProcessing = false;
typeInstance->mTypeIncomplete = false;
auto checkBaseType = typeInstance->mBaseType;
auto checkBaseType = typeInstance->GetImplBaseType();
while (checkBaseType != NULL)
{
PopulateType(checkBaseType, BfPopulateType_Full_Force);
BF_ASSERT((!checkBaseType->IsIncomplete()) || (checkBaseType->mTypeFailed));
checkBaseType = checkBaseType->mBaseType;
checkBaseType = checkBaseType->GetImplBaseType();
}
if ((mCompiler->mOptions.mHasVDataExtender) && (!typeInstance->IsInterface()))
@ -3733,8 +3751,8 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance)
BF_ASSERT(mCompiler->mOptions.mHasVDataExtender);
if (methodRef.mTypeInstance == typeInstance)
{
if (typeInstance->mBaseType != NULL)
BF_ASSERT(methodIdx == (int)typeInstance->mBaseType->mVirtualMethodTableSize);
if (typeInstance->GetImplBaseType() != NULL)
BF_ASSERT(methodIdx == (int)typeInstance->GetImplBaseType()->mVirtualMethodTableSize);
}
continue;
}
@ -3782,7 +3800,7 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance)
{
// Attempt to find matching entries in base types
ambiguityContext.mIsReslotting = true;
auto checkType = typeInstance->mBaseType;
auto checkType = typeInstance->GetImplBaseType();
while (checkType != NULL)
{
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)
{
if (resolvedTypeRef->IsPointer())
resolvedTypeRef = ((BfPointerType*)resolvedTypeRef)->mElementType;
bool isStructPtr = false;
// if (resolvedTypeRef->IsPointer())
// resolvedTypeRef = ((BfPointerType*)resolvedTypeRef)->mElementType;
if (resolvedTypeRef->IsPrimitiveType())
{
auto primType = (BfPrimitiveType*)resolvedTypeRef;
@ -4641,10 +4661,18 @@ BfBoxedType* BfModule::CreateBoxedType(BfType* resolvedTypeRef)
else if (resolvedTypeRef->IsPointer())
{
BfPointerType* pointerType = (BfPointerType*)resolvedTypeRef;
if (pointerType->mElementType->IsStruct())
{
resolvedTypeRef = pointerType->mElementType;
isStructPtr = true;
}
else
{
BfTypeVector typeVector;
typeVector.Add(pointerType->mElementType);
resolvedTypeRef = ResolveTypeDef(mCompiler->mPointerTTypeDef, typeVector, BfPopulateType_Data)->ToTypeInstance();
}
}
else if (resolvedTypeRef->IsMethodRef())
{
BfMethodRefType* methodRefType = (BfMethodRefType*)resolvedTypeRef;
@ -4670,6 +4698,7 @@ BfBoxedType* BfModule::CreateBoxedType(BfType* resolvedTypeRef)
boxedType->mContext = mContext;
boxedType->mElementType = typeInst;
boxedType->mTypeDef = boxedType->mElementType->mTypeDef;
boxedType->mBoxedFlags = isStructPtr ? BfBoxedType::BoxedFlags_StructPtr : BfBoxedType::BoxedFlags_None;
auto resolvedBoxedType = ResolveType(boxedType);
if (resolvedBoxedType != boxedType)
mContext->mBoxedTypePool.GiveBack(boxedType);
@ -6904,7 +6933,6 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula
auto outerType = typeDef->mOuterType;
BF_ASSERT(!outerType->mIsPartial);
if (TypeHasParent(mCurTypeInstance->mTypeDef, outerType))
{
BfType* checkCurType = mCurTypeInstance;
if (checkCurType->IsBoxed())
@ -6975,24 +7003,6 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula
InitType(typeInst, populateType);
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))
{
if (arrayTypeRef->mDimensions > 4)
@ -10059,13 +10069,24 @@ bool BfModule::TypeIsSubTypeOf(BfTypeInstance* srcType, BfTypeInstance* wantType
return true;
}
}
checkType = checkType->mBaseType;
checkType = checkType->GetImplBaseType();
if ((checkType != NULL) && (checkType->mDefineState < BfTypeDefineState_HasInterfaces))
{
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;
}
@ -10243,9 +10264,11 @@ void BfModule::DoTypeToString(StringImpl& str, BfType* resolvedType, BfTypeNameF
if (resolvedType->IsBoxed())
{
auto boxedeType = (BfBoxedType*)resolvedType;
auto boxedType = (BfBoxedType*)resolvedType;
str += "boxed ";
DoTypeToString(str, boxedeType->mElementType, typeNameFlags, genericMethodNameOverrides);
DoTypeToString(str, boxedType->mElementType, typeNameFlags, genericMethodNameOverrides);
if (boxedType->mBoxedFlags == BfBoxedType::BoxedFlags_StructPtr)
str += "*";
return;
}
else if ((resolvedType->IsArray()) && ((typeNameFlags & BfTypeNameFlag_UseArrayImplType) == 0))

View file

@ -1087,6 +1087,7 @@ BfMethodInstanceGroup::~BfMethodInstanceGroup()
BfTypeInstance::~BfTypeInstance()
{
delete mTypeInfoEx;
delete mCustomAttributes;
delete mAttributeData;
for (auto methodInst : mInternalMethods)
@ -1622,17 +1623,25 @@ BfType* BfTypeInstance::GetUnderlyingType()
if (!mIsTypedPrimitive)
return NULL;
if (mTypeInfoEx == NULL)
mTypeInfoEx = new BfTypeInfoEx();
if (mTypeInfoEx->mUnderlyingType != NULL)
return mTypeInfoEx->mUnderlyingType;
auto checkTypeInst = this;
while (checkTypeInst != NULL)
{
if (!checkTypeInst->mFieldInstances.empty())
return checkTypeInst->mFieldInstances.back().mResolvedType;
{
mTypeInfoEx->mUnderlyingType = checkTypeInst->mFieldInstances.back().mResolvedType;
return mTypeInfoEx->mUnderlyingType;
}
checkTypeInst = checkTypeInst->mBaseType;
if (checkTypeInst->IsIncomplete())
mModule->PopulateType(checkTypeInst, BfPopulateType_Data);
}
BF_FATAL("Failed");
return NULL;
return mTypeInfoEx->mUnderlyingType;
}
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()
{
if (mBaseType == NULL)
@ -2461,11 +2479,6 @@ int BfResolvedTypeSet::Hash(BfTypeReference* typeRef, LookupContext* ctx, BfHash
hashVal = ((hashVal ^ (Hash(nullableType->mElementType, ctx))) << 5) - 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))
{
if ((flags & BfHashFlag_AllowRef) != 0)
@ -2656,6 +2669,8 @@ bool BfResolvedTypeSet::Equals(BfType* lhs, BfType* rhs, LookupContext* ctx)
return false;
BfBoxedType* lhsBoxedType = (BfBoxedType*)lhs;
BfBoxedType* rhsBoxedType = (BfBoxedType*)rhs;
if (lhsBoxedType->mBoxedFlags != rhsBoxedType->mBoxedFlags)
return false;
return Equals(lhsBoxedType->mElementType, rhsBoxedType->mElementType, ctx);
}
else if (lhs->IsArray())
@ -3050,11 +3065,7 @@ bool BfResolvedTypeSet::Equals(BfType* lhs, BfTypeReference* rhs, LookupContext*
if (lhs->IsBoxed())
{
auto rhsBoxedTypeRef = BfNodeDynCastExact<BfBoxedTypeRef>(rhs);
if (rhsBoxedTypeRef == NULL)
return false;
BfBoxedType* lhsBoxedType = (BfBoxedType*) lhs;
return Equals(lhsBoxedType->mElementType, rhsBoxedTypeRef->mElementType, ctx);
}
else if (lhs->IsArray())
{
@ -3701,8 +3712,6 @@ String BfTypeUtils::TypeToString(BfTypeReference* typeRef)
if (auto ptrType = BfNodeDynCast<BfPointerTypeRef>(typeRef))
return TypeToString(ptrType->mElementType) + "*";
if (auto boxedType = BfNodeDynCast<BfBoxedTypeRef>(typeRef))
return "boxed " + TypeToString(boxedType->mElementType);
if (auto ptrType = BfNodeDynCast<BfArrayTypeRef>(typeRef))
{
String name = TypeToString(ptrType->mElementType) + "[";

View file

@ -450,6 +450,7 @@ public:
virtual bool IsTypedPrimitive() { return false; }
virtual bool IsComposite() { return IsStruct(); }
virtual bool IsStruct() { return false; }
virtual bool IsStructPtr() { return false; }
virtual bool IsUnion() { return false; }
virtual bool IsStructOrStructPtr() { return false; }
virtual bool IsObject() { return false; }
@ -494,6 +495,7 @@ public:
virtual bool WantsGCMarking() { return false; }
virtual BfTypeCode GetLoweredType() { return BfTypeCode_None; }
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 IsTypeMemberAccessible(BfTypeDef* declaringTypeDef, BfTypeDef* activeTypeDef) { return true; }
virtual bool IsTypeMemberAccessible(BfTypeDef* declaringTypeDef, BfProject* curProject) { return true; }
@ -1451,6 +1453,21 @@ public:
Array<BfTypeInstance*> mStaticTypes;
};
class BfTypeInfoEx
{
public:
BfType* mUnderlyingType;
int64 mMinValue;
int64 mMaxValue;
BfTypeInfoEx()
{
mUnderlyingType = NULL;
mMinValue = 0;
mMaxValue = 0;
}
};
// Instance of struct or class
class BfTypeInstance : public BfDependedType
{
@ -1465,6 +1482,7 @@ public:
BfTypeInstance* mBaseType;
BfCustomAttributes* mCustomAttributes;
BfAttributeData* mAttributeData;
BfTypeInfoEx* mTypeInfoEx;
Array<BfTypeInterfaceEntry> mInterfaces;
Array<BfTypeInterfaceMethodEntry> mInterfaceMethodTable;
@ -1528,6 +1546,7 @@ public:
mBaseType = NULL;
mCustomAttributes = NULL;
mAttributeData = NULL;
mTypeInfoEx = NULL;
//mClassVData = NULL;
mVirtualMethodTableSize = 0;
mHotTypeData = NULL;
@ -1566,6 +1585,7 @@ public:
virtual BfTypeInstance* ToTypeInstance() override { return this; }
virtual bool IsDependentOnUnderlyingType() override { return true; }
virtual BfPrimitiveType* ToPrimitiveType() override { return GetUnderlyingType()->ToPrimitiveType(); }
virtual bool HasWrappedRepresentation() { return IsTypedPrimitive(); }
int GetEndingInstanceAlignment() { if (mInstSize % mInstAlign == 0) return mInstAlign; return mInstSize % mInstAlign; }
virtual bool HasTypeFailed() override { return mTypeFailed; }
@ -1602,6 +1622,8 @@ public:
virtual bool WantsGCMarking() override;
virtual BfTypeCode GetLoweredType() override;
virtual BfTypeInstance* GetImplBaseType() { return mBaseType; }
virtual bool IsIRFuncUsed(BfIRFunction func);
void CalcHotVirtualData(/*Val128& vtHash, */Array<int>* ifaceMapping);
@ -1626,9 +1648,25 @@ public:
class BfBoxedType : public BfTypeInstance
{
public:
BfTypeInstance* mElementType;
enum BoxedFlags
{
BoxedFlags_None = 0,
BoxedFlags_StructPtr = 1
};
public:
BfTypeInstance* mElementType;
BfBoxedType* mBoxedBaseType;
BoxedFlags mBoxedFlags;
public:
BfBoxedType()
{
mElementType = NULL;
mBoxedBaseType = NULL;
mBoxedFlags = BoxedFlags_None;
}
virtual bool IsBoxed() override { return true; }
virtual bool IsValueType() override { return false; }
@ -1645,6 +1683,15 @@ public:
virtual bool IsSpecializedType() override { return !mElementType->IsUnspecializedType(); }
virtual bool IsUnspecializedType() override { return mElementType->IsUnspecializedType(); }
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
@ -1862,6 +1909,7 @@ public:
virtual bool IsReified() { return mElementType->IsReified(); }
virtual bool IsPointer() 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 IsValueTypeOrValueTypePtr() override { return mElementType->IsValueType(); }
virtual bool IsDependentOnUnderlyingType() override { return true; }
@ -2174,7 +2222,7 @@ public:
}
mCount++;
Entry* entry = new Entry();
Entry* entry = (Entry*)BfResolvedTypeSetFuncs::Allocate(sizeof(Entry), alignof(Entry));
entry->mValue = NULL;
// if (mHashHeads[bucket] != NULL)
// mHashHeads[bucket]->mPrev = entry;

View file

@ -582,25 +582,7 @@ BOOL WINAPI DllMain(
DWORD dwReason,
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)
{
@ -641,57 +623,9 @@ static _CrtMemState gStartMemCheckpoint;
#endif
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
//_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*/);
//_CrtSetAllocHook(BfAllocHook);

View file

@ -9,10 +9,9 @@ namespace Tests
int Get() mut;
}
struct Struct : IFace
struct StructA : IFace
{
public int mA = 100;
public int mB = 200;
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]
public static void TestBasics()
{
Struct val0 = .();
Object obj0 = val0;
StructA valA = .();
Object obj0 = valA;
IFace iface0 = (IFace)obj0;
Test.Assert(GetFromIFace(mut valA) == 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 = .();
Object obj1 = (Object)(ref val1);
IFace iface1 = (IFace)obj1;
StructB valB = .();
IFace iface1 = valB;
Test.Assert(GetFromIFace(mut valB) == 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);
}
}
}