diff --git a/IDEHelper/Compiler/BfAst.h b/IDEHelper/Compiler/BfAst.h index 811adeaf..da4d56e6 100644 --- a/IDEHelper/Compiler/BfAst.h +++ b/IDEHelper/Compiler/BfAst.h @@ -3,6 +3,7 @@ #include "BeefySysLib/Common.h" #include "BeefySysLib/util/DLIList.h" #include "BeefySysLib/util/BumpAllocator.h" +#include "BeefySysLib/util/SizedArray.h" #include "BfAstAllocator.h" #include "BfIRBuilder.h" @@ -767,6 +768,23 @@ public: class BfAstNode; +class BfAstNodeList +{ +public: + SizedArray mList; + +public: + bool operator==(const BfAstNodeList& rhs) + { + if (mList.mSize != rhs.mList.mSize) + return false; + for (int i = 0; i < mList.mSize; i++) + if (mList[i] != rhs.mList[i]) + return false; + return false; + } +}; + template class BfChunkedArray { @@ -3299,4 +3317,20 @@ BfUnaryOp BfTokenToUnaryOp(BfToken token); BfAssignmentOp BfTokenToAssignmentOp(BfToken token); bool BfIsCommentBlock(BfCommentKind commentKind); -NS_BF_END \ No newline at end of file +NS_BF_END + +namespace std +{ + template<> + struct hash + { + size_t operator()(const Beefy::BfAstNodeList& val) const + { + if (val.mList.mSize == 0) + return 0; + if (val.mList.mSize == 0) + return (size_t)val.mList.mVals[0]; + return HashBytes((uint8*)val.mList.mVals, sizeof(Beefy::BfAstNode*) * val.mList.mSize); + } + }; +} diff --git a/IDEHelper/Compiler/BfExprEvaluator.cpp b/IDEHelper/Compiler/BfExprEvaluator.cpp index 85983951..cb260364 100644 --- a/IDEHelper/Compiler/BfExprEvaluator.cpp +++ b/IDEHelper/Compiler/BfExprEvaluator.cpp @@ -2598,17 +2598,19 @@ BfType* BfExprEvaluator::BindGenericType(BfAstNode* node, BfType* bindType) return bindType; int64 nodeId = ((int64)parser->mDataId << 32) + node->GetSrcStart(); + auto genericTypeBindings = mModule->mCurMethodState->GetRootMethodState()->mGenericTypeBindings; + if (mModule->mCurMethodInstance->mIsUnspecialized) { if (!bindType->IsGenericParam()) return bindType; - (*mModule->mCurMethodState->mGenericTypeBindings)[nodeId] = bindType; + (*genericTypeBindings)[nodeId] = bindType; return bindType; } else { - if (mModule->mCurMethodState->mGenericTypeBindings == NULL) + if (genericTypeBindings == NULL) return bindType; /*auto itr = mModule->mCurMethodState->mGenericTypeBindings->find(nodeId); @@ -2616,7 +2618,7 @@ BfType* BfExprEvaluator::BindGenericType(BfAstNode* node, BfType* bindType) return itr->second;*/ BfType** typePtr = NULL; - if (mModule->mCurMethodState->mGenericTypeBindings->TryGetValue(nodeId, &typePtr)) + if (genericTypeBindings->TryGetValue(nodeId, &typePtr)) return *typePtr; return bindType; @@ -10780,10 +10782,24 @@ void BfExprEvaluator::VisitLambdaBodies(BfAstNode* body, BfFieldDtorDeclaration* } BfLambdaInstance* BfExprEvaluator::GetLambdaInstance(BfLambdaBindExpression* lambdaBindExpr, BfAllocTarget& allocTarget) -{ - auto rootMethodState = mModule->mCurMethodState->GetRootMethodState(); +{ + auto rootMethodState = mModule->mCurMethodState->GetRootMethodState(); + BfAstNodeList cacheNodeList; + cacheNodeList.mList.Add(lambdaBindExpr); + + /// + { + auto checkMethodState = mModule->mCurMethodState; + while (checkMethodState != NULL) + { + if (checkMethodState->mMixinState != NULL) + cacheNodeList.mList.Add(checkMethodState->mMixinState->mSource); + checkMethodState = checkMethodState->mPrevMethodState; + } + } + BfLambdaInstance* lambdaInstance = NULL; - if (rootMethodState->mLambdaCache.TryGetValue(lambdaBindExpr, &lambdaInstance)) + if (rootMethodState->mLambdaCache.TryGetValue(cacheNodeList, &lambdaInstance)) return lambdaInstance; static int sBindCount = 0; @@ -11628,7 +11644,7 @@ BfLambdaInstance* BfExprEvaluator::GetLambdaInstance(BfLambdaBindExpression* lam methodState.Reset(); lambdaInstance = new BfLambdaInstance(); - rootMethodState->mLambdaCache[lambdaBindExpr] = lambdaInstance; + rootMethodState->mLambdaCache[cacheNodeList] = lambdaInstance; lambdaInstance->mDelegateTypeInstance = delegateTypeInstance; lambdaInstance->mUseTypeInstance = useTypeInstance; lambdaInstance->mClosureTypeInstance = closureTypeInst; diff --git a/IDEHelper/Compiler/BfModule.h b/IDEHelper/Compiler/BfModule.h index 43baa50a..33e519be 100644 --- a/IDEHelper/Compiler/BfModule.h +++ b/IDEHelper/Compiler/BfModule.h @@ -943,7 +943,7 @@ public: Dictionary mLocalMethodCache; // So any lambda 'capturing' and 'processing' stages use the same local method Array mDeferredLocalMethods; OwnedVector mMixinStates; - Dictionary mLambdaCache; + Dictionary mLambdaCache; Array mDeferredLambdaInstances; Array mSplatDecompAddrs; BfDeferredLocalAssignData* mDeferredLocalAssignData; @@ -1955,5 +1955,5 @@ namespace std { return std::hash()(val.mLocalVar->mName); } - }; + }; }