From ceb400d57359f54a280c906455df5d8a13597e89 Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Tue, 8 Feb 2022 10:33:20 -0500 Subject: [PATCH] Handled generic depth limitation for pointers, delegates, tuples, arrays --- IDEHelper/Compiler/BfCompiler.cpp | 2 +- IDEHelper/Compiler/BfExprEvaluator.cpp | 10 +----- IDEHelper/Compiler/BfModuleTypeUtils.cpp | 25 ++++++++------ IDEHelper/Compiler/BfResolvedTypeUtils.cpp | 40 ++++++++++++---------- IDEHelper/Compiler/BfResolvedTypeUtils.h | 39 +++++++++++++++++++-- 5 files changed, 74 insertions(+), 42 deletions(-) diff --git a/IDEHelper/Compiler/BfCompiler.cpp b/IDEHelper/Compiler/BfCompiler.cpp index 347924ab..160518da 100644 --- a/IDEHelper/Compiler/BfCompiler.cpp +++ b/IDEHelper/Compiler/BfCompiler.cpp @@ -578,7 +578,7 @@ bool BfCompiler::IsTypeUsed(BfType* checkType, BfProject* curProject) if (checkType->IsPointer()) return IsTypeUsed(((BfPointerType*)checkType)->mElementType, curProject); if (checkType->IsRef()) - return IsTypeUsed(((BfPointerType*)checkType)->mElementType, curProject); + return IsTypeUsed(((BfRefType*)checkType)->mElementType, curProject); return true; } diff --git a/IDEHelper/Compiler/BfExprEvaluator.cpp b/IDEHelper/Compiler/BfExprEvaluator.cpp index 0abe0207..72e6cbfc 100644 --- a/IDEHelper/Compiler/BfExprEvaluator.cpp +++ b/IDEHelper/Compiler/BfExprEvaluator.cpp @@ -15196,19 +15196,11 @@ BfTypedValue BfExprEvaluator::MakeCallableTarget(BfAstNode* targetSrc, BfTypedVa { auto underlying = target.mType->GetUnderlyingType(); bool underlyingIsStruct = underlying->IsStruct(); -// if (underlying->IsGenericParam()) -// { -// auto genericParam = mModule->GetGenericParamInstance((BfGenericParamType*)underlying); -// if (((genericParam->mTypeConstraint != NULL) && (genericParam->mTypeConstraint->IsValueType())) || -// ((genericParam->mGenericParamFlags & (BfGenericParamFlag_Struct)) != 0)) -// underlyingIsStruct = true; -// } if (underlyingIsStruct) { - auto pointerType = (BfPointerType*)target.mType; target = mModule->LoadValue(target); - target.mType = pointerType->mElementType; + target.mType = underlying; target.mKind = BfTypedValueKind_Addr; } } diff --git a/IDEHelper/Compiler/BfModuleTypeUtils.cpp b/IDEHelper/Compiler/BfModuleTypeUtils.cpp index 3cb08739..a8bc79a0 100644 --- a/IDEHelper/Compiler/BfModuleTypeUtils.cpp +++ b/IDEHelper/Compiler/BfModuleTypeUtils.cpp @@ -7930,7 +7930,7 @@ BfType* BfModule::ResolveGenericType(BfType* unspecializedType, BfTypeVector* ty auto baseType = (BfTypeInstance*)ResolveTypeDef(mContext->mCompiler->mValueTypeTypeDef); - BfTypeInstance* tupleType = NULL; + BfTupleType* tupleType = NULL; if (wantGeneric) { Array genericArgs; @@ -7950,6 +7950,7 @@ BfType* BfModule::ResolveGenericType(BfType* unspecializedType, BfTypeVector* ty auto actualTupleType = mContext->mTupleTypePool.Get(); delete actualTupleType->mGenericTypeInfo; + actualTupleType->mGenericDepth = 0; actualTupleType->mGenericTypeInfo = new BfGenericTypeInfo(); actualTupleType->mGenericTypeInfo->mIsUnspecialized = false; actualTupleType->mGenericTypeInfo->mIsUnspecializedVariation = false; @@ -7991,7 +7992,7 @@ BfType* BfModule::ResolveGenericType(BfType* unspecializedType, BfTypeVector* ty for (int fieldIdx = 0; fieldIdx < (int)fieldTypes.size(); fieldIdx++) { String fieldName = fieldNames[fieldIdx]; - BfFieldDef* fieldDef = actualTupleType->AddField(fieldName); + BfFieldDef* fieldDef = actualTupleType->AddField(fieldName); } tupleType = actualTupleType; @@ -8005,6 +8006,7 @@ BfType* BfModule::ResolveGenericType(BfType* unspecializedType, BfTypeVector* ty fieldInstance->mFieldIdx = fieldIdx; fieldInstance->SetResolvedType(fieldTypes[fieldIdx]); fieldInstance->mOwner = tupleType; + tupleType->mGenericDepth = BF_MAX(tupleType->mGenericDepth, fieldInstance->mResolvedType->GetGenericDepth() + 1); } bool failed = false; @@ -10556,6 +10558,7 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula arrayType->mElementType = elementType; arrayType->mElementCount = elementCount; arrayType->mWantsGCMarking = false; // Fill in in InitType + arrayType->mGenericDepth = elementType->GetGenericDepth() + 1; resolvedEntry->mValue = arrayType; BF_ASSERT(BfResolvedTypeSet::Hash(arrayType, &lookupCtx) == resolvedEntry->mHash); @@ -10723,12 +10726,8 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula for (auto genericArgRef : genericArguments) { auto genericArg = genericArgs[genericParamIdx + startDefGenericParamIdx]; - - if (auto genericGenericArg = genericArg->ToGenericTypeInstance()) - { - genericTypeInst->mGenericTypeInfo->mMaxGenericDepth = BF_MAX(genericTypeInst->mGenericTypeInfo->mMaxGenericDepth, genericGenericArg->mGenericTypeInfo->mMaxGenericDepth + 1); - } - + + genericTypeInst->mGenericTypeInfo->mMaxGenericDepth = BF_MAX(genericTypeInst->mGenericTypeInfo->mMaxGenericDepth, genericArg->GetGenericDepth() + 1); genericTypeInst->mGenericTypeInfo->mTypeGenericArguments.push_back(genericArg); genericTypeInst->mGenericTypeInfo->mTypeGenericArgumentRefs.push_back(genericArgRef); @@ -10814,7 +10813,7 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula wantGeneric = false; auto baseType = (BfTypeInstance*)ResolveTypeDef(mContext->mCompiler->mValueTypeTypeDef, BfPopulateType_Identity); - BfTypeInstance* tupleType = NULL; + BfTupleType* tupleType = NULL; if (wantGeneric) { BfTupleType* actualTupleType = new BfTupleType(); @@ -10873,6 +10872,7 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula fieldInstance->SetResolvedType(types[fieldIdx]); BF_ASSERT(!types[fieldIdx]->IsVar()); fieldInstance->mOwner = tupleType; + tupleType->mGenericDepth = BF_MAX(tupleType->mGenericDepth, fieldInstance->mResolvedType->GetGenericDepth() + 1); } resolvedEntry->mValue = tupleType; @@ -10928,6 +10928,7 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula return ResolveTypeResult(typeRef, elementType, populateType, resolveFlags); } + pointerType->mGenericDepth = elementType->GetGenericDepth() + 1; pointerType->mElementType = elementType; pointerType->mContext = mContext; resolvedEntry->mValue = pointerType; @@ -11070,7 +11071,7 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula failed = true; BfDelegateInfo* delegateInfo = NULL; - BfTypeInstance* delegateType = NULL; + BfDelegateType* delegateType = NULL; if (wantGeneric) { BfDelegateType* genericTypeInst = new BfDelegateType(); @@ -11164,6 +11165,8 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula delegateInfo->mHasExplicitThis = functionThisType != NULL; delegateInfo->mHasVarArgs = hasVarArgs; + delegateType->mGenericDepth = BF_MAX(delegateType->mGenericDepth, returnType->GetGenericDepth() + 1); + auto hashVal = mContext->mResolvedTypes.Hash(typeRef, &lookupCtx); //int paramSrcOfs = (functionThisType != NULL) ? 1 : 0; @@ -11195,6 +11198,8 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula methodDef->mParams.push_back(paramDef); delegateInfo->mParams.Add(paramType); + + delegateType->mGenericDepth = BF_MAX(delegateType->mGenericDepth, paramType->GetGenericDepth() + 1); } if (delegateInfo->mHasVarArgs) diff --git a/IDEHelper/Compiler/BfResolvedTypeUtils.cpp b/IDEHelper/Compiler/BfResolvedTypeUtils.cpp index db8ae513..358c60bc 100644 --- a/IDEHelper/Compiler/BfResolvedTypeUtils.cpp +++ b/IDEHelper/Compiler/BfResolvedTypeUtils.cpp @@ -2706,6 +2706,7 @@ BfTupleType::BfTupleType() mTypeDef = NULL; mIsUnspecializedType = false; mIsUnspecializedTypeVariation = false; + mGenericDepth = 0; } BfTupleType::~BfTupleType() @@ -2973,8 +2974,8 @@ int BfResolvedTypeSet::DoHash(BfType* type, LookupContext* ctx, bool allowRef, i int hashVal = HASH_DELEGATE; auto delegateInfo = type->GetDelegateInfo(); - - hashVal = ((hashVal ^ (Hash(delegateInfo->mReturnType, ctx, BfHashFlag_None, hashSeed))) << 5) - hashVal; + + hashVal = HASH_MIX(hashVal, Hash(delegateInfo->mReturnType, ctx, BfHashFlag_None, hashSeed + 1)); auto methodDef = typeInst->mTypeDef->mMethods[0]; BF_ASSERT(methodDef->mName == "Invoke"); @@ -2987,15 +2988,15 @@ int BfResolvedTypeSet::DoHash(BfType* type, LookupContext* ctx, bool allowRef, i for (int paramIdx = 0; paramIdx < delegateInfo->mParams.size(); paramIdx++) { - // Parse attributes? - hashVal = ((hashVal ^ (Hash(delegateInfo->mParams[paramIdx], ctx, BfHashFlag_None, hashSeed))) << 5) - hashVal; + // Parse attributes? + hashVal = HASH_MIX(hashVal, Hash(delegateInfo->mParams[paramIdx], ctx, BfHashFlag_None, hashSeed + 1)); String paramName = methodDef->mParams[paramIdx]->mName; int nameHash = (int)Hash64(paramName.c_str(), (int)paramName.length()); - hashVal = ((hashVal ^ (nameHash)) << 5) - hashVal; + hashVal = HASH_MIX(hashVal, nameHash); } - if (delegateInfo->mHasVarArgs) - hashVal = ((hashVal ^ HASH_DOTDOTDOT) << 5) - hashVal; + if (delegateInfo->mHasVarArgs) + hashVal = HASH_MIX(hashVal, HASH_DOTDOTDOT); return hashVal; } @@ -3022,8 +3023,9 @@ int BfResolvedTypeSet::DoHash(BfType* type, LookupContext* ctx, bool allowRef, i { BfFieldInstance* fieldInstance = &tupleType->mFieldInstances[fieldIdx]; - auto fieldType = fieldInstance->mResolvedType; - hashVal = ((hashVal ^ (Hash(fieldType, ctx, BfHashFlag_None, hashSeed))) << 5) - hashVal; + auto fieldType = fieldInstance->mResolvedType; + hashVal = HASH_MIX(hashVal, Hash(fieldType, ctx, BfHashFlag_None, hashSeed + 1)); + BfFieldDef* fieldDef = NULL; if (tupleType->mTypeDef != NULL) fieldDef = fieldInstance->GetFieldDef(); @@ -3036,9 +3038,9 @@ int BfResolvedTypeSet::DoHash(BfType* type, LookupContext* ctx, bool allowRef, i } else { - nameHash = (int)Hash64(fieldDef->mName.c_str(), (int)fieldDef->mName.length()); + nameHash = (int)Hash64(fieldDef->mName.c_str(), (int)fieldDef->mName.length()); } - hashVal = ((hashVal ^ (nameHash)) << 5) - hashVal; + hashVal = HASH_MIX(hashVal, nameHash); } } else if (type->IsGenericTypeInstance()) @@ -3354,8 +3356,8 @@ int BfResolvedTypeSet::DoHash(BfTypeReference* typeRef, LookupContext* ctx, BfHa for (int fieldIdx = 0; fieldIdx < (int)tupleTypeRef->mFieldTypes.size(); fieldIdx++) { - BfTypeReference* fieldType = tupleTypeRef->mFieldTypes[fieldIdx]; - hashVal = ((hashVal ^ (Hash(fieldType, ctx, BfHashFlag_None, hashSeed))) << 5) - hashVal; + BfTypeReference* fieldType = tupleTypeRef->mFieldTypes[fieldIdx]; + hashVal = HASH_MIX(hashVal, Hash(fieldType, ctx, BfHashFlag_None, hashSeed + 1)); int nameHash = 0; BfIdentifierNode* fieldName = NULL; @@ -3372,7 +3374,7 @@ int BfResolvedTypeSet::DoHash(BfTypeReference* typeRef, LookupContext* ctx, BfHa sprintf(nameStr, "%d", fieldIdx); nameHash = (int)Hash64(nameStr, strlen(nameStr)); } - hashVal = ((hashVal ^ (nameHash)) << 5) - hashVal; + hashVal = HASH_MIX(hashVal, nameHash); } return hashVal; @@ -3594,7 +3596,7 @@ int BfResolvedTypeSet::DoHash(BfTypeReference* typeRef, LookupContext* ctx, BfHa { int hashVal = HASH_DELEGATE; if (delegateTypeRef->mReturnType != NULL) - hashVal = ((hashVal ^ (Hash(delegateTypeRef->mReturnType, ctx, BfHashFlag_AllowRef, hashSeed))) << 5) - hashVal; + hashVal = HASH_MIX(hashVal, Hash(delegateTypeRef->mReturnType, ctx, BfHashFlag_AllowRef, hashSeed + 1)); else ctx->mFailed = true; @@ -3620,16 +3622,16 @@ int BfResolvedTypeSet::DoHash(BfTypeReference* typeRef, LookupContext* ctx, BfHa if (auto dotTypeRef = BfNodeDynCastExact(fieldType)) { if (dotTypeRef->mDotToken->mToken == BfToken_DotDotDot) - { - hashVal = ((hashVal ^ HASH_DOTDOTDOT) << 5) - hashVal; + { + hashVal = HASH_MIX(hashVal, HASH_DOTDOTDOT); continue; } } } if (fieldType != NULL) - hashVal = ((hashVal ^ (Hash(fieldType, ctx, (BfHashFlags)(BfHashFlag_AllowRef), hashSeed))) << 5) - hashVal; - hashVal = ((hashVal ^ (HashNode(param->mNameNode))) << 5) - hashVal; + hashVal = HASH_MIX(hashVal, Hash(fieldType, ctx, (BfHashFlags)(BfHashFlag_AllowRef), hashSeed + 1)); + hashVal = HASH_MIX(hashVal, HashNode(param->mNameNode)); isFirstParam = true; } diff --git a/IDEHelper/Compiler/BfResolvedTypeUtils.h b/IDEHelper/Compiler/BfResolvedTypeUtils.h index a721e183..4b35ee81 100644 --- a/IDEHelper/Compiler/BfResolvedTypeUtils.h +++ b/IDEHelper/Compiler/BfResolvedTypeUtils.h @@ -524,6 +524,7 @@ public: virtual BfTypeInstance* ToGenericTypeInstance() { return NULL; } virtual BfPrimitiveType* ToPrimitiveType() { return NULL; } virtual bool IsDependendType() { return false; } + virtual int GetGenericDepth() { return 0; } virtual bool IsTypeInstance() { return false; } virtual bool IsGenericTypeInstance() { return false; } virtual bool IsUnspecializedType() { return false; } @@ -616,6 +617,20 @@ public: virtual void ReportMemory(MemReporter* memReporter); }; +class BfElementedType : public BfType +{ +public: + int mGenericDepth; + +public: + BfElementedType() + { + mGenericDepth = 0; + } + + virtual int GetGenericDepth() override { return mGenericDepth; } +}; + // This is explicitly used for generics typedef SizedArray BfTypeVector; typedef SizedArray BfTypeRefVector; @@ -2029,6 +2044,7 @@ public: virtual bool GetLoweredType(BfTypeUsage typeUsage, BfTypeCode* outTypeCode = NULL, BfTypeCode* outTypeCode2 = NULL) override; BfGenericTypeInfo* GetGenericTypeInfo() { return mGenericTypeInfo; } + virtual int GetGenericDepth() { return (mGenericTypeInfo != NULL) ? mGenericTypeInfo->mMaxGenericDepth : 0; } virtual BfTypeInstance* ToGenericTypeInstance() override { return (mGenericTypeInfo != NULL) ? this : NULL; } virtual bool IsGenericTypeInstance() override { return mGenericTypeInfo != NULL; } @@ -2205,12 +2221,14 @@ public: BfDelegateInfo mDelegateInfo; bool mIsUnspecializedType; bool mIsUnspecializedTypeVariation; + int mGenericDepth; public: BfDelegateType() { mIsUnspecializedType = false; mIsUnspecializedTypeVariation = false; + mGenericDepth = 0; } ~BfDelegateType(); @@ -2228,16 +2246,18 @@ public: virtual bool IsUnspecializedTypeVariation() override { return mIsUnspecializedTypeVariation; } virtual BfDelegateInfo* GetDelegateInfo() override { return &mDelegateInfo; } + virtual int GetGenericDepth() override { return mGenericDepth; } }; class BfTupleType : public BfTypeInstance { -public: +public: bool mCreatedTypeDef; String mNameAdd; BfSource* mSource; bool mIsUnspecializedType; bool mIsUnspecializedTypeVariation; + int mGenericDepth; public: BfTupleType(); @@ -2252,6 +2272,8 @@ public: virtual bool IsUnspecializedType() override { return mIsUnspecializedType; } virtual bool IsUnspecializedTypeVariation() override { return mIsUnspecializedTypeVariation; } + + virtual int GetGenericDepth() override { return mGenericDepth; } }; class BfConcreteInterfaceType : public BfType @@ -2266,7 +2288,7 @@ public: virtual bool IsUnspecializedTypeVariation() override { return mInterface->IsUnspecializedTypeVariation(); } }; -class BfPointerType : public BfType +class BfPointerType : public BfElementedType { public: BfType* mElementType; @@ -2395,9 +2417,18 @@ class BfSizedArrayType : public BfDependedType public: BfType* mElementType; intptr mElementCount; + int mGenericDepth; bool mWantsGCMarking; public: + BfSizedArrayType() + { + mElementType = NULL; + mElementCount = 0; + mGenericDepth = 0; + mWantsGCMarking = false; + } + virtual bool NeedsExplicitAlignment() override { return mElementType->NeedsExplicitAlignment(); } virtual bool IsSizedArray() override { return true; } @@ -2417,6 +2448,8 @@ public: virtual bool IsUnspecializedTypeVariation() override { return mElementType->IsUnspecializedTypeVariation(); } virtual bool CanBeValuelessType() override { return true; } virtual bool WantsGCMarking() override { BF_ASSERT(mDefineState >= BfTypeDefineState_Defined); return mWantsGCMarking; } + + virtual int GetGenericDepth() override { return mGenericDepth; } // Leave the default "zero sized" definition //virtual bool IsValuelessType() override { return mElementType->IsValuelessType(); } }; @@ -2727,7 +2760,7 @@ public: else if (checkType->IsPointer()) GetProjectList(((BfPointerType*)checkType)->mElementType, projectList, immutableLength); else if (checkType->IsRef()) - GetProjectList(((BfPointerType*)checkType)->mElementType, projectList, immutableLength); + GetProjectList(((BfRefType*)checkType)->mElementType, projectList, immutableLength); else if (checkType->IsSizedArray()) GetProjectList(((BfSizedArrayType*)checkType)->mElementType, projectList, immutableLength); else if (checkType->IsMethodRef())