diff --git a/IDEHelper/Compiler/BfDefBuilder.cpp b/IDEHelper/Compiler/BfDefBuilder.cpp index e0f9a2f1..a3930925 100644 --- a/IDEHelper/Compiler/BfDefBuilder.cpp +++ b/IDEHelper/Compiler/BfDefBuilder.cpp @@ -585,8 +585,7 @@ BfMethodDef* BfDefBuilder::CreateMethodDef(BfMethodDeclaration* methodDeclaratio { if (methodDeclaration->mNameNode != NULL) methodDef->mName = methodDeclaration->mNameNode->ToString(); - methodDef->mMethodType = BfMethodType_Mixin; - methodDef->mIsNoSplat = true; + methodDef->mMethodType = BfMethodType_Mixin; } else { diff --git a/IDEHelper/Compiler/BfExprEvaluator.cpp b/IDEHelper/Compiler/BfExprEvaluator.cpp index 1c42069c..4391811b 100644 --- a/IDEHelper/Compiler/BfExprEvaluator.cpp +++ b/IDEHelper/Compiler/BfExprEvaluator.cpp @@ -5322,7 +5322,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance* { if (paramType->IsStruct()) { - if ((!doingThis) || (!methodDef->mIsMutating && methodInstance->AllowsSplatting())) + if ((!doingThis) || (!methodDef->mIsMutating && methodInstance->AllowsSplatting(paramIdx))) { BfTypeCode loweredTypeCode = BfTypeCode_None; BfTypeCode loweredTypeCode2 = BfTypeCode_None; @@ -5778,7 +5778,7 @@ void BfExprEvaluator::PushThis(BfAstNode* targetSrc, BfTypedValue argVal, BfMeth if (mModule->mIsConstModule) allowThisSplatting = owner->IsTypedPrimitive() || owner->IsValuelessType(); else - allowThisSplatting = methodInstance->AllowsThisSplatting(); + allowThisSplatting = methodInstance->AllowsSplatting(-1); if ((!allowThisSplatting) || (methodDef->mIsMutating)) { @@ -5788,7 +5788,7 @@ void BfExprEvaluator::PushThis(BfAstNode* targetSrc, BfTypedValue argVal, BfMeth } auto thisType = methodInstance->GetThisType(); - PushArg(argVal, irArgs, !methodInstance->AllowsThisSplatting(), thisType->IsPointer()); + PushArg(argVal, irArgs, !methodInstance->AllowsSplatting(-1), thisType->IsPointer()); } void BfExprEvaluator::FinishDeferredEvals(SizedArrayImpl& argValues) @@ -10832,7 +10832,7 @@ void BfExprEvaluator::Visit(BfDelegateBindExpression* delegateBindExpr) bool isStructTarget = (target) && (target.mType->IsStruct()); bool bindCapturesThis = bindMethodInstance->HasThis() && !isStructTarget; - bool needsSplat = (isStructTarget) && (!bindMethodInstance->mMethodDef->mIsMutating) && (bindMethodInstance->AllowsSplatting()); + bool needsSplat = (isStructTarget) && (!bindMethodInstance->mMethodDef->mIsMutating) && (bindMethodInstance->AllowsSplatting(-1)); bool captureThisByValue = isStructTarget; if (bindMethodInstance->mMethodDef->mIsLocalMethod) { diff --git a/IDEHelper/Compiler/BfModule.cpp b/IDEHelper/Compiler/BfModule.cpp index 3d193cc7..e39df23d 100644 --- a/IDEHelper/Compiler/BfModule.cpp +++ b/IDEHelper/Compiler/BfModule.cpp @@ -15565,6 +15565,11 @@ void BfModule::SetupIRMethod(BfMethodInstance* methodInstance, BfIRFunction func if ((methodInstance->HasThis()) && (!methodDef->mHasExplicitThis)) paramIdx = -1; + if (methodInstance->mMethodDef->mName == "Invoke@GetFFIType$wPb") + { + NOP; + } + int argCount = methodInstance->GetIRFunctionParamCount(this); while (argIdx < argCount) @@ -15593,8 +15598,8 @@ void BfModule::SetupIRMethod(BfMethodInstance* methodInstance, BfIRFunction func resolvedTypeRef = mCurMethodState->mClosureState->mClosureType; else resolvedTypeRef = methodInstance->GetThisType(); - isSplattable = (!mIsConstModule) && (resolvedTypeRef->IsSplattable()) && (methodInstance->AllowsThisSplatting()); - tryLowering = (!mIsConstModule) && (methodInstance->AllowsThisSplatting()); + isSplattable = (!mIsConstModule) && (resolvedTypeRef->IsSplattable()) && (methodInstance->AllowsSplatting(-1)); + tryLowering = (!mIsConstModule) && (methodInstance->AllowsSplatting(-1)); } else { @@ -15602,7 +15607,7 @@ void BfModule::SetupIRMethod(BfMethodInstance* methodInstance, BfIRFunction func resolvedTypeRef = methodInstance->GetParamType(paramIdx); if (resolvedTypeRef->IsMethodRef()) isSplattable = true; - else if ((!mIsConstModule) && (resolvedTypeRef->IsSplattable()) && (methodInstance->AllowsSplatting())) + else if ((!mIsConstModule) && (resolvedTypeRef->IsSplattable()) && (methodInstance->AllowsSplatting(paramIdx))) { auto resolvedTypeInst = resolvedTypeRef->ToTypeInstance(); if ((resolvedTypeInst != NULL) && (resolvedTypeInst->mIsCRepr)) @@ -16756,7 +16761,7 @@ void BfModule::ProcessMethod_SetupParams(BfMethodInstance* methodInstance, BfTyp else paramVar->mValue = mBfIRBuilder->GetFakeVal(); - if ((!mIsConstModule) && (thisType->IsSplattable()) && (methodInstance->AllowsThisSplatting())) + if ((!mIsConstModule) && (thisType->IsSplattable()) && (methodInstance->AllowsSplatting(-1))) { if (!thisType->IsTypedPrimitive()) paramVar->mIsSplat = true; @@ -16848,9 +16853,9 @@ void BfModule::ProcessMethod_SetupParams(BfMethodInstance* methodInstance, BfTyp { paramVar->mIsSplat = true; } - else if ((resolvedType->IsComposite()) && (resolvedType->IsSplattable())) + else if ((!mIsConstModule) && (resolvedType->IsComposite()) && (resolvedType->IsSplattable())) { - if ((!mIsConstModule) && (methodInstance->AllowsSplatting())) + if (methodInstance->AllowsSplatting(paramIdx)) { int splatCount = resolvedType->GetSplatCount(); if (argIdx + splatCount <= mCompiler->mOptions.mMaxSplatRegs) @@ -21563,7 +21568,7 @@ genericParam->mExternType = GetPrimitiveType(BfTypeCode_Var); { methodParam.mIsSplat = true; } - else if ((checkType->IsComposite()) && (methodInstance->AllowsSplatting())) + else if ((checkType->IsComposite()) && (methodInstance->AllowsSplatting(paramIdx))) { PopulateType(checkType, BfPopulateType_Data); if (checkType->IsSplattable()) diff --git a/IDEHelper/Compiler/BfResolvedTypeUtils.cpp b/IDEHelper/Compiler/BfResolvedTypeUtils.cpp index 72269233..2d870a64 100644 --- a/IDEHelper/Compiler/BfResolvedTypeUtils.cpp +++ b/IDEHelper/Compiler/BfResolvedTypeUtils.cpp @@ -733,7 +733,7 @@ int BfMethodInstance::GetStructRetIdx(bool forceStatic) return 0; if (!owner->IsValueType()) return 1; - if ((mMethodDef->mIsMutating) || (!owner->IsSplattable()) || ((!AllowsThisSplatting()) && (!owner->GetLoweredType(BfTypeUsage_Parameter)))) + if ((mMethodDef->mIsMutating) || (!owner->IsSplattable()) || ((!AllowsSplatting(-1)) && (!owner->GetLoweredType(BfTypeUsage_Parameter)))) return 1; return 0; } @@ -800,22 +800,28 @@ bool BfMethodInstance::IsTestMethod() (mMethodInfoEx->mMethodCustomAttributes->mCustomAttributes != NULL) && (mMethodInfoEx->mMethodCustomAttributes->mCustomAttributes->Contains(GetOwner()->mModule->mCompiler->mTestAttributeTypeDef)); } -bool BfMethodInstance::AllowsSplatting() +bool BfMethodInstance::AllowsSplatting(int paramIdx) { - if (mCallingConvention != BfCallingConvention_Unspecified) - return false; - if (mMethodDef->mIsNoSplat) - return false; - return true; -} - -bool BfMethodInstance::AllowsThisSplatting() -{ - if (mCallingConvention != BfCallingConvention_Unspecified) - return false; - if (mMethodDef->mIsNoSplat) - return false; - return !mMethodDef->HasNoThisSplat(); + if (paramIdx == -1) + { + if (mCallingConvention != BfCallingConvention_Unspecified) + return false; + if (mMethodDef->mIsNoSplat) + return false; + return !mMethodDef->HasNoThisSplat(); + } + else + { + if (mCallingConvention != BfCallingConvention_Unspecified) + return false; + if ((mMethodDef->mIsNoSplat) || (mMethodDef->mMethodType == BfMethodType_Mixin)) + { + if (IsImplicitCapture(paramIdx)) + return true; + return false; + } + return true; + } } bool BfMethodInstance::HasThis() @@ -839,7 +845,7 @@ BfType* BfMethodInstance::GetThisType() { auto thisType = mParams[0].mResolvedType; auto owner = GetOwner(); - if ((thisType->IsValueType()) && ((mMethodDef->mIsMutating) || (!AllowsSplatting())) && (!thisType->GetLoweredType(BfTypeUsage_Parameter))) + if ((thisType->IsValueType()) && ((mMethodDef->mIsMutating) || (!AllowsSplatting(-1))) && (!thisType->GetLoweredType(BfTypeUsage_Parameter))) return owner->mModule->CreatePointerType(thisType); return thisType; } @@ -926,7 +932,7 @@ BfType* BfMethodInstance::GetParamType(int paramIdx, bool returnUnderlyingParams { BF_FATAL("Wrong 'this' index"); } - if ((thisType->IsValueType()) && ((mMethodDef->mIsMutating) || (!AllowsSplatting())) && (!thisType->GetLoweredType(BfTypeUsage_Parameter))) + if ((thisType->IsValueType()) && ((mMethodDef->mIsMutating) || (!AllowsSplatting(paramIdx))) && (!thisType->GetLoweredType(BfTypeUsage_Parameter))) return owner->mModule->CreatePointerType(thisType); return thisType; } @@ -959,7 +965,7 @@ bool BfMethodInstance::GetParamIsSplat(int paramIdx) { BF_ASSERT(!mMethodDef->mIsStatic); auto owner = mMethodInstanceGroup->mOwner; - if ((owner->IsValueType()) && (mMethodDef->mIsMutating || !AllowsSplatting())) + if ((owner->IsValueType()) && (mMethodDef->mIsMutating || !AllowsSplatting(paramIdx))) return false; return owner->mIsSplattable; } @@ -1172,7 +1178,7 @@ void BfMethodInstance::GetIRFunctionInfo(BfModule* module, BfIRType& returnType, { checkType = checkType->GetUnderlyingType(); } - else if ((!module->mIsConstModule) && (checkType->IsSplattable()) && (AllowsThisSplatting())) + else if ((!module->mIsConstModule) && (checkType->IsSplattable()) && (AllowsSplatting(-1))) { doSplat = true; } @@ -1189,7 +1195,7 @@ void BfMethodInstance::GetIRFunctionInfo(BfModule* module, BfIRType& returnType, { checkType = checkType->GetUnderlyingType(); } - else if ((!module->mIsConstModule) && (checkType->IsSplattable()) && (AllowsSplatting())) + else if ((!module->mIsConstModule) && (checkType->IsSplattable()) && (AllowsSplatting(paramIdx))) { doSplat = true; } diff --git a/IDEHelper/Compiler/BfResolvedTypeUtils.h b/IDEHelper/Compiler/BfResolvedTypeUtils.h index 36413bd6..02fcb20a 100644 --- a/IDEHelper/Compiler/BfResolvedTypeUtils.h +++ b/IDEHelper/Compiler/BfResolvedTypeUtils.h @@ -906,8 +906,7 @@ public: bool AlwaysInline(); BfImportCallKind GetImportCallKind(); bool IsTestMethod(); - bool AllowsSplatting(); - bool AllowsThisSplatting(); + bool AllowsSplatting(int paramIdx); int GetParamCount(); int GetImplicitParamCount(); void GetParamName(int paramIdx, StringImpl& name);