mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-08 19:48:20 +02:00
Boxing result change, warning on boxing obj, boxing generics
This commit is contained in:
parent
17fbd8f8d6
commit
d6566982f2
4 changed files with 60 additions and 27 deletions
|
@ -1939,7 +1939,7 @@ void BfMethodMatcher::TryDevirtualizeCall(BfTypedValue target, BfTypedValue* ori
|
||||||
auto boxedMethodInstance = useModule->ReferenceExternalMethodInstance(methodRef.mImplementingMethod);
|
auto boxedMethodInstance = useModule->ReferenceExternalMethodInstance(methodRef.mImplementingMethod);
|
||||||
|
|
||||||
BfBoxedType* vBoxedType = (BfBoxedType*)methodRef.mImplementingMethod.mTypeInstance;
|
BfBoxedType* vBoxedType = (BfBoxedType*)methodRef.mImplementingMethod.mTypeInstance;
|
||||||
mBestMethodTypeInstance = vBoxedType->mElementType;
|
mBestMethodTypeInstance = vBoxedType->mElementType->ToTypeInstance();
|
||||||
mBestMethodInstance = mModule->GetMethodInstance(mBestMethodTypeInstance, boxedMethodInstance.mMethodInstance->mMethodDef, BfTypeVector());
|
mBestMethodInstance = mModule->GetMethodInstance(mBestMethodTypeInstance, boxedMethodInstance.mMethodInstance->mMethodDef, BfTypeVector());
|
||||||
mBestMethodDef = mBestMethodInstance.mMethodInstance->mMethodDef;
|
mBestMethodDef = mBestMethodInstance.mMethodInstance->mMethodDef;
|
||||||
}
|
}
|
||||||
|
@ -11752,38 +11752,45 @@ void BfExprEvaluator::Visit(BfBoxExpression* boxExpr)
|
||||||
auto exprValue = mModule->CreateValueFromExpression(boxExpr->mExpression);
|
auto exprValue = mModule->CreateValueFromExpression(boxExpr->mExpression);
|
||||||
if (exprValue)
|
if (exprValue)
|
||||||
{
|
{
|
||||||
|
bool doFail = false;
|
||||||
|
bool doWarn = false;
|
||||||
|
|
||||||
if (exprValue.mType->IsGenericParam())
|
if (exprValue.mType->IsGenericParam())
|
||||||
{
|
{
|
||||||
BF_ASSERT(mModule->mCurMethodInstance->mIsUnspecialized);
|
BF_ASSERT(mModule->mCurMethodInstance->mIsUnspecialized);
|
||||||
|
|
||||||
auto genericParamTarget = (BfGenericParamType*)exprValue.mType;
|
auto genericParamTarget = (BfGenericParamType*)exprValue.mType;
|
||||||
auto genericParamInstance = mModule->GetGenericParamInstance(genericParamTarget);
|
auto genericParamInstance = mModule->GetGenericParamInstance(genericParamTarget);
|
||||||
bool isBoxable = false;
|
|
||||||
|
if ((genericParamInstance->mGenericParamFlags & (BfGenericParamFlag_Struct | BfGenericParamFlag_StructPtr | BfGenericParamFlag_Class)) == BfGenericParamFlag_Class)
|
||||||
|
doWarn = true;
|
||||||
|
|
||||||
if (genericParamInstance->mGenericParamFlags & (BfGenericParamFlag_Struct | BfGenericParamFlag_StructPtr))
|
if ((genericParamInstance->mTypeConstraint != NULL) && (genericParamInstance->mTypeConstraint->IsObjectOrInterface()))
|
||||||
isBoxable = true;
|
doWarn = true;
|
||||||
|
}
|
||||||
if ((genericParamInstance->mTypeConstraint != NULL) && (exprValue.mType->IsValueTypeOrValueTypePtr()))
|
else
|
||||||
isBoxable = true;
|
{
|
||||||
|
doFail = !exprValue.mType->IsValueTypeOrValueTypePtr();
|
||||||
if (isBoxable)
|
doWarn = exprValue.mType->IsObjectOrInterface();
|
||||||
{
|
|
||||||
mResult = mModule->GetDefaultTypedValue(mModule->mContext->mBfObjectType);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!exprValue.mType->IsValueTypeOrValueTypePtr())
|
if (doWarn)
|
||||||
|
{
|
||||||
|
mModule->Warn(0, StrFormat("Boxing is unnecessary since type '%s' is already a reference type.", mModule->TypeToString(exprValue.mType).c_str()), boxExpr->mExpression);
|
||||||
|
mResult = exprValue;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (doFail)
|
||||||
{
|
{
|
||||||
mModule->Fail(StrFormat("Box target '%s' must be a value type or pointer to a value type", mModule->TypeToString(exprValue.mType).c_str()), boxExpr->mExpression);
|
mModule->Fail(StrFormat("Box target '%s' must be a value type or pointer to a value type", mModule->TypeToString(exprValue.mType).c_str()), boxExpr->mExpression);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//BfType* boxedType = mModule->CreateBoxedType(exprValue.mType);
|
BfType* boxedType = mModule->CreateBoxedType(exprValue.mType);
|
||||||
|
if (boxedType == NULL)
|
||||||
//auto scopeData = mModule->FindScope(boxExpr->mAllocNode);
|
boxedType = mModule->mContext->mBfObjectType;
|
||||||
|
mResult = mModule->BoxValue(boxExpr->mExpression, exprValue, boxedType, allocTarget);
|
||||||
mResult = mModule->BoxValue(boxExpr->mExpression, exprValue, mModule->mContext->mBfObjectType, allocTarget);
|
|
||||||
if (!mResult)
|
if (!mResult)
|
||||||
{
|
{
|
||||||
mModule->Fail(StrFormat("Type '%s' is not boxable", mModule->TypeToString(exprValue.mType).c_str()), boxExpr->mExpression);
|
mModule->Fail(StrFormat("Type '%s' is not boxable", mModule->TypeToString(exprValue.mType).c_str()), boxExpr->mExpression);
|
||||||
|
|
|
@ -3653,7 +3653,7 @@ void BfModule::CreateDynamicCastMethod()
|
||||||
if (mCurTypeInstance->IsBoxed())
|
if (mCurTypeInstance->IsBoxed())
|
||||||
{
|
{
|
||||||
BfBoxedType* boxedType = (BfBoxedType*)mCurTypeInstance;
|
BfBoxedType* boxedType = (BfBoxedType*)mCurTypeInstance;
|
||||||
BfTypeInstance* innerType = boxedType->mElementType;
|
BfTypeInstance* innerType = boxedType->mElementType->ToTypeInstance();
|
||||||
|
|
||||||
FindSubTypes(innerType, &typeMatches, &exChecks, isInterfacePass);
|
FindSubTypes(innerType, &typeMatches, &exChecks, isInterfacePass);
|
||||||
|
|
||||||
|
@ -8425,6 +8425,14 @@ BfTypedValue BfModule::BoxValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp
|
||||||
{
|
{
|
||||||
if (toType == mContext->mBfObjectType)
|
if (toType == mContext->mBfObjectType)
|
||||||
return BfTypedValue(mBfIRBuilder->GetFakeVal(), toType);
|
return BfTypedValue(mBfIRBuilder->GetFakeVal(), toType);
|
||||||
|
if (toType->IsBoxed())
|
||||||
|
{
|
||||||
|
BfBoxedType* boxedType = (BfBoxedType*)toType;
|
||||||
|
if (typedVal.mType == boxedType->mElementType)
|
||||||
|
return BfTypedValue(mBfIRBuilder->GetFakeVal(), toType);
|
||||||
|
else
|
||||||
|
return BfTypedValue();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BP_ZONE("BoxValue");
|
BP_ZONE("BoxValue");
|
||||||
|
@ -16900,7 +16908,7 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup)
|
||||||
mBfIRBuilder->ClearDebugLocation();
|
mBfIRBuilder->ClearDebugLocation();
|
||||||
|
|
||||||
BfBoxedType* boxedType = (BfBoxedType*) mCurTypeInstance;
|
BfBoxedType* boxedType = (BfBoxedType*) mCurTypeInstance;
|
||||||
BfTypeInstance* innerType = boxedType->mElementType;
|
BfTypeInstance* innerType = boxedType->mElementType->ToTypeInstance();
|
||||||
PopulateType(innerType, BfPopulateType_DataAndMethods);
|
PopulateType(innerType, BfPopulateType_DataAndMethods);
|
||||||
mBfIRBuilder->PopulateType(mCurTypeInstance);
|
mBfIRBuilder->PopulateType(mCurTypeInstance);
|
||||||
BfGetMethodInstanceFlags flags = BfGetMethodInstanceFlag_None;
|
BfGetMethodInstanceFlags flags = BfGetMethodInstanceFlag_None;
|
||||||
|
@ -19246,7 +19254,7 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool
|
||||||
{
|
{
|
||||||
auto boxedType = (BfBoxedType*)mCurTypeInstance;
|
auto boxedType = (BfBoxedType*)mCurTypeInstance;
|
||||||
// If we failed a lookup here then we better have also failed it in the original type
|
// If we failed a lookup here then we better have also failed it in the original type
|
||||||
BF_ASSERT(boxedType->mElementType->mModule->mHadBuildError || mContext->mFailTypes.Contains(boxedType->mElementType));
|
BF_ASSERT(boxedType->mElementType->ToTypeInstance()->mModule->mHadBuildError || mContext->mFailTypes.Contains(boxedType->mElementType->ToTypeInstance()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4774,13 +4774,16 @@ BfBoxedType* BfModule::CreateBoxedType(BfType* resolvedTypeRef)
|
||||||
}
|
}
|
||||||
|
|
||||||
BfTypeInstance* typeInst = resolvedTypeRef->ToTypeInstance();
|
BfTypeInstance* typeInst = resolvedTypeRef->ToTypeInstance();
|
||||||
if (typeInst == NULL)
|
if ((typeInst == NULL) && (!resolvedTypeRef->IsGenericParam()))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
auto boxedType = mContext->mBoxedTypePool.Get();
|
auto boxedType = mContext->mBoxedTypePool.Get();
|
||||||
boxedType->mContext = mContext;
|
boxedType->mContext = mContext;
|
||||||
boxedType->mElementType = typeInst;
|
boxedType->mElementType = resolvedTypeRef;
|
||||||
boxedType->mTypeDef = boxedType->mElementType->mTypeDef;
|
if (typeInst != NULL)
|
||||||
|
boxedType->mTypeDef = typeInst->mTypeDef;
|
||||||
|
else
|
||||||
|
boxedType->mTypeDef = mCompiler->mValueTypeTypeDef;
|
||||||
boxedType->mBoxedFlags = isStructPtr ? BfBoxedType::BoxedFlags_StructPtr : BfBoxedType::BoxedFlags_None;
|
boxedType->mBoxedFlags = isStructPtr ? BfBoxedType::BoxedFlags_StructPtr : BfBoxedType::BoxedFlags_None;
|
||||||
auto resolvedBoxedType = ResolveType(boxedType);
|
auto resolvedBoxedType = ResolveType(boxedType);
|
||||||
if (resolvedBoxedType != boxedType)
|
if (resolvedBoxedType != boxedType)
|
||||||
|
@ -9102,6 +9105,21 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (typedVal.mType->IsBoxed())
|
||||||
|
{
|
||||||
|
BfBoxedType* boxedType = (BfBoxedType*)typedVal.mType;
|
||||||
|
if (boxedType->mElementType->IsGenericParam())
|
||||||
|
{
|
||||||
|
// If we have a boxed generic param, the actual available interfaces constraints won't be
|
||||||
|
// handled, so we need to pass through again as the root generic param
|
||||||
|
BfTypedValue unboxedValue = typedVal;
|
||||||
|
unboxedValue.mType = boxedType->mElementType;
|
||||||
|
auto result = CastToValue(srcNode, unboxedValue, toType, (BfCastFlags)(castFlags | BfCastFlags_SilentFail), resultFlags);
|
||||||
|
if (result)
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (mayBeBox)
|
if (mayBeBox)
|
||||||
{
|
{
|
||||||
BfScopeData* scopeData = NULL;
|
BfScopeData* scopeData = NULL;
|
||||||
|
|
|
@ -1579,7 +1579,7 @@ public:
|
||||||
Array<BfVirtualMethodEntry> mVirtualMethodTable;
|
Array<BfVirtualMethodEntry> mVirtualMethodTable;
|
||||||
BfHotTypeData* mHotTypeData;
|
BfHotTypeData* mHotTypeData;
|
||||||
int mVirtualMethodTableSize; // With hot reloading, mVirtualMethodTableSize can be larger than mInterfaceMethodTable (live vtable versioning)
|
int mVirtualMethodTableSize; // With hot reloading, mVirtualMethodTableSize can be larger than mInterfaceMethodTable (live vtable versioning)
|
||||||
Array<BfFieldInstance> mFieldInstances;
|
Array<BfFieldInstance> mFieldInstances;
|
||||||
Array<BfMethodInstance*> mInternalMethods;
|
Array<BfMethodInstance*> mInternalMethods;
|
||||||
Dictionary<BfTypeDef*, BfStaticSearch> mStaticSearchMap;
|
Dictionary<BfTypeDef*, BfStaticSearch> mStaticSearchMap;
|
||||||
bool mHasStaticInitMethod;
|
bool mHasStaticInitMethod;
|
||||||
|
@ -1744,7 +1744,7 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
BfTypeInstance* mElementType;
|
BfType* mElementType;
|
||||||
BfBoxedType* mBoxedBaseType;
|
BfBoxedType* mBoxedBaseType;
|
||||||
BoxedFlags mBoxedFlags;
|
BoxedFlags mBoxedFlags;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue