瀏覽代碼

Deferred Import dynamic/static check, fix calling convention

Brian Fiete 5 年之前
父節點
當前提交
42452fe09c

+ 7 - 0
BeefySysLib/platform/PlatformInterface.h

@@ -4,6 +4,11 @@
 
 
 #define BFP_VERSION 2
 #define BFP_VERSION 2
 
 
+#ifdef BFP_INTERNAL
+#define BFP_EXPORT
+#define BFP_CALLTYPE
+#else
+
 #ifndef BFP_EXPORT
 #ifndef BFP_EXPORT
 #define BFP_EXPORT BF_EXPORT
 #define BFP_EXPORT BF_EXPORT
 #endif
 #endif
@@ -12,6 +17,8 @@
 #define BFP_CALLTYPE BF_CALLTYPE
 #define BFP_CALLTYPE BF_CALLTYPE
 #endif
 #endif
 
 
+#endif
+
 // Windows file time (the number of 100-nanosecond intervals that have elapsed since 12:00 A.M. January 1, 1601 Coordinated Universal Time (UTC))
 // Windows file time (the number of 100-nanosecond intervals that have elapsed since 12:00 A.M. January 1, 1601 Coordinated Universal Time (UTC))
 typedef uint64 BfpTimeStamp;
 typedef uint64 BfpTimeStamp;
 
 

+ 1 - 1
BeefySysLib/util/ThreadPool.cpp

@@ -134,7 +134,7 @@ void ThreadPool::SetStackSize(int stackSize)
 	mStackSize = stackSize;
 	mStackSize = stackSize;
 }
 }
 
 
-static void WorkerProc(void* param)
+static void BFP_CALLTYPE WorkerProc(void* param)
 {
 {
 	((ThreadPool::Thread*)param)->Proc();
 	((ThreadPool::Thread*)param)->Proc();
 }
 }

+ 1 - 1
BeefySysLib/util/WorkThread.cpp

@@ -16,7 +16,7 @@ WorkThread::~WorkThread()
 	mThread = NULL;
 	mThread = NULL;
 }
 }
 
 
-static void WorkThreadStub(void* param)
+static void BFP_CALLTYPE WorkThreadStub(void* param)
 {
 {
 	((WorkThread*)param)->Run();
 	((WorkThread*)param)->Run();
 }
 }

+ 1 - 1
IDEHelper/COFF.cpp

@@ -4898,7 +4898,7 @@ bool COFF::CvParseDBI(int wantAge)
 		bool isV2 = sig == 0xf13151e4;
 		bool isV2 = sig == 0xf13151e4;
 		if (isV2)
 		if (isV2)
 		{
 		{
-			Fail("ERROR: FastLink PDBs are not supported. Consider adding full debug info (/DEBUG:FULL).");
+			Fail("FastLink PDBs are not supported. Consider adding full debug info (/DEBUG:FULL).");
 			mIsFastLink = true;
 			mIsFastLink = true;
 		}
 		}
 
 

+ 2 - 0
IDEHelper/Compiler/BfCompiler.cpp

@@ -379,6 +379,7 @@ BfCompiler::BfCompiler(BfSystem* bfSystem, bool isResolveOnly)
 	mBfObjectTypeDef = NULL;
 	mBfObjectTypeDef = NULL;
 	mClassVDataTypeDef = NULL;
 	mClassVDataTypeDef = NULL;
 	mCLinkAttributeTypeDef = NULL;
 	mCLinkAttributeTypeDef = NULL;
+	mImportAttributeTypeDef = NULL;
 	mCReprAttributeTypeDef = NULL;
 	mCReprAttributeTypeDef = NULL;
 	mAlignAttributeTypeDef = NULL;
 	mAlignAttributeTypeDef = NULL;
 	mNoDiscardAttributeTypeDef = NULL;
 	mNoDiscardAttributeTypeDef = NULL;
@@ -5837,6 +5838,7 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory)
 	mBfObjectTypeDef = _GetRequiredType("System.Object");	
 	mBfObjectTypeDef = _GetRequiredType("System.Object");	
 	mClassVDataTypeDef = _GetRequiredType("System.ClassVData");
 	mClassVDataTypeDef = _GetRequiredType("System.ClassVData");
 	mCLinkAttributeTypeDef = _GetRequiredType("System.CLinkAttribute");
 	mCLinkAttributeTypeDef = _GetRequiredType("System.CLinkAttribute");
+	mImportAttributeTypeDef = _GetRequiredType("System.ImportAttribute");
 	mCReprAttributeTypeDef = _GetRequiredType("System.CReprAttribute");
 	mCReprAttributeTypeDef = _GetRequiredType("System.CReprAttribute");
 	mAlignAttributeTypeDef = _GetRequiredType("System.AlignAttribute");
 	mAlignAttributeTypeDef = _GetRequiredType("System.AlignAttribute");
 	mNoDiscardAttributeTypeDef = _GetRequiredType("System.NoDiscardAttribute");
 	mNoDiscardAttributeTypeDef = _GetRequiredType("System.NoDiscardAttribute");

+ 3 - 2
IDEHelper/Compiler/BfCompiler.h

@@ -374,9 +374,10 @@ public:
 	BfTypeDef* mAttributeTypeDef;
 	BfTypeDef* mAttributeTypeDef;
 	BfTypeDef* mAttributeUsageAttributeTypeDef;
 	BfTypeDef* mAttributeUsageAttributeTypeDef;
 	BfTypeDef* mLinkNameAttributeTypeDef;
 	BfTypeDef* mLinkNameAttributeTypeDef;
-	BfTypeDef* mOrderedAttributeTypeDef;
-	BfTypeDef* mInlineAttributeTypeDef;
+	BfTypeDef* mOrderedAttributeTypeDef;	
+	BfTypeDef* mInlineAttributeTypeDef;	
 	BfTypeDef* mCLinkAttributeTypeDef;
 	BfTypeDef* mCLinkAttributeTypeDef;
+	BfTypeDef* mImportAttributeTypeDef;
 	BfTypeDef* mCReprAttributeTypeDef;
 	BfTypeDef* mCReprAttributeTypeDef;
 	BfTypeDef* mAlignAttributeTypeDef;
 	BfTypeDef* mAlignAttributeTypeDef;
 	BfTypeDef* mNoDiscardAttributeTypeDef;
 	BfTypeDef* mNoDiscardAttributeTypeDef;

+ 4 - 9
IDEHelper/Compiler/BfDefBuilder.cpp

@@ -717,7 +717,7 @@ void BfDefBuilder::ParseAttributes(BfAttributeDirective* attributes, BfMethodDef
 			}
 			}
 			else if (typeRefName == "Import")
 			else if (typeRefName == "Import")
 			{
 			{
-				methodDef->mImportKind = BfImportKind_Static;
+				methodDef ->mImportKind = BfImportKind_Import_Unknown;
 				if (!attributes->mArguments.IsEmpty())
 				if (!attributes->mArguments.IsEmpty())
 				{
 				{
 					if (auto literalExpr = BfNodeDynCast<BfLiteralExpression>(attributes->mArguments[0]))
 					if (auto literalExpr = BfNodeDynCast<BfLiteralExpression>(attributes->mArguments[0]))
@@ -725,12 +725,7 @@ void BfDefBuilder::ParseAttributes(BfAttributeDirective* attributes, BfMethodDef
 						if (literalExpr->mValue.mTypeCode == BfTypeCode_CharPtr)
 						if (literalExpr->mValue.mTypeCode == BfTypeCode_CharPtr)
 						{
 						{
 							String filePath = *literalExpr->mValue.mString;
 							String filePath = *literalExpr->mValue.mString;
-							String fileExt = GetFileExtension(filePath);
-							if ((fileExt.Equals(".DLL", StringImpl::CompareKind_OrdinalIgnoreCase)) ||
-								(fileExt.Equals(".EXE", StringImpl::CompareKind_OrdinalIgnoreCase)))
-							{
-								methodDef->mImportKind = BfImportKind_Dynamic;
-							}
+							methodDef->mImportKind = BfMethodDef::GetImportKindFromPath(filePath);							
 						}
 						}
 					}
 					}
 				}
 				}
@@ -752,7 +747,7 @@ void BfDefBuilder::ParseAttributes(BfAttributeDirective* attributes, BfMethodDef
 				else
 				else
 				{
 				{
 					methodDef->mCommutableKind = BfCommutableKind_Forward;
 					methodDef->mCommutableKind = BfCommutableKind_Forward;
-				}				
+				}
 			}
 			}
 		}
 		}
 
 
@@ -1799,7 +1794,7 @@ void BfDefBuilder::FinishTypeDef(bool wantsToString)
 			}			
 			}			
 		}
 		}
 
 
-		if (method->mImportKind == BfImportKind_Dynamic)
+		if ((method->mImportKind == BfImportKind_Import_Dynamic) || (method->mImportKind == BfImportKind_Import_Unknown))
 			needsStaticInit = true;
 			needsStaticInit = true;
 	}
 	}
 	
 	

+ 8 - 5
IDEHelper/Compiler/BfExprEvaluator.cpp

@@ -4296,7 +4296,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfMethodInstance* methodInstance, BfIRV
 		firstArg = irArgs[0];
 		firstArg = irArgs[0];
 	
 	
 	auto methodInstOwner = methodInstance->GetOwner();
 	auto methodInstOwner = methodInstance->GetOwner();
-	auto expectCallingConvention = mModule->GetCallingConvention(methodInstOwner, methodDef);
+	auto expectCallingConvention = mModule->GetIRCallingConvention(methodInstOwner, methodDef);
 	if ((methodInstOwner->IsFunction()) && (methodInstance->GetParamCount() > 0) && (methodInstance->GetParamName(0) == "this"))
 	if ((methodInstOwner->IsFunction()) && (methodInstance->GetParamCount() > 0) && (methodInstance->GetParamName(0) == "this"))
 	{
 	{
 		auto paramType = methodInstance->GetParamType(0);
 		auto paramType = methodInstance->GetParamType(0);
@@ -9031,7 +9031,7 @@ void BfExprEvaluator::Visit(BfDelegateBindExpression* delegateBindExpr)
 					auto funcType = mModule->mBfIRBuilder->CreateFunctionType(irReturnType, irParamTypes);
 					auto funcType = mModule->mBfIRBuilder->CreateFunctionType(irReturnType, irParamTypes);
 					auto funcValue = mModule->mBfIRBuilder->CreateFunction(funcType, BfIRLinkageType_External, methodName);
 					auto funcValue = mModule->mBfIRBuilder->CreateFunction(funcType, BfIRLinkageType_External, methodName);
 
 
-					auto srcCallingConv = mModule->GetCallingConvention(methodInstance->GetOwner(), methodInstance->mMethodDef);
+					auto srcCallingConv = mModule->GetIRCallingConvention(methodInstance);
 					mModule->mBfIRBuilder->SetFuncCallingConv(funcValue, srcCallingConv);
 					mModule->mBfIRBuilder->SetFuncCallingConv(funcValue, srcCallingConv);
 
 
 					mModule->mBfIRBuilder->SetActiveFunction(funcValue);
 					mModule->mBfIRBuilder->SetActiveFunction(funcValue);
@@ -9048,7 +9048,7 @@ void BfExprEvaluator::Visit(BfDelegateBindExpression* delegateBindExpr)
 					if (mModule->mCompiler->mOptions.mAllowHotSwapping)
 					if (mModule->mCompiler->mOptions.mAllowHotSwapping)
 						bindFuncVal = mModule->mBfIRBuilder->RemapBindFunction(bindFuncVal);
 						bindFuncVal = mModule->mBfIRBuilder->RemapBindFunction(bindFuncVal);
 					auto callResult = mModule->mBfIRBuilder->CreateCall(bindFuncVal, irArgs);
 					auto callResult = mModule->mBfIRBuilder->CreateCall(bindFuncVal, irArgs);
-					auto destCallingConv = mModule->GetCallingConvention(bindMethodInstance->GetOwner(), bindMethodInstance->mMethodDef);
+					auto destCallingConv = mModule->GetIRCallingConvention(bindMethodInstance);
 					if (destCallingConv != BfIRCallingConv_CDecl)
 					if (destCallingConv != BfIRCallingConv_CDecl)
 						mModule->mBfIRBuilder->SetCallCallingConv(callResult, destCallingConv);
 						mModule->mBfIRBuilder->SetCallCallingConv(callResult, destCallingConv);
 					if (methodInstance->mReturnType->IsValuelessType())
 					if (methodInstance->mReturnType->IsValuelessType())
@@ -9285,7 +9285,7 @@ void BfExprEvaluator::Visit(BfDelegateBindExpression* delegateBindExpr)
 		auto funcType = mModule->mBfIRBuilder->CreateFunctionType(irReturnType, irParamTypes);
 		auto funcType = mModule->mBfIRBuilder->CreateFunctionType(irReturnType, irParamTypes);
 		funcValue = mModule->mBfIRBuilder->CreateFunction(funcType, BfIRLinkageType_External, methodName);
 		funcValue = mModule->mBfIRBuilder->CreateFunction(funcType, BfIRLinkageType_External, methodName);
 
 
-		auto srcCallingConv = mModule->GetCallingConvention(methodInstance->GetOwner(), methodInstance->mMethodDef);
+		auto srcCallingConv = mModule->GetIRCallingConvention(methodInstance);
 		if ((!hasThis) && (methodInstance->mMethodDef->mCallingConvention == BfCallingConvention_Stdcall))
 		if ((!hasThis) && (methodInstance->mMethodDef->mCallingConvention == BfCallingConvention_Stdcall))
 			srcCallingConv = BfIRCallingConv_StdCall;
 			srcCallingConv = BfIRCallingConv_StdCall;
 		mModule->mBfIRBuilder->SetFuncCallingConv(funcValue, srcCallingConv);
 		mModule->mBfIRBuilder->SetFuncCallingConv(funcValue, srcCallingConv);
@@ -9334,7 +9334,7 @@ void BfExprEvaluator::Visit(BfDelegateBindExpression* delegateBindExpr)
 		if (mModule->mCompiler->mOptions.mAllowHotSwapping)
 		if (mModule->mCompiler->mOptions.mAllowHotSwapping)
 			bindFuncVal = mModule->mBfIRBuilder->RemapBindFunction(bindFuncVal);
 			bindFuncVal = mModule->mBfIRBuilder->RemapBindFunction(bindFuncVal);
 		auto result = mModule->mBfIRBuilder->CreateCall(bindFuncVal, irArgs);
 		auto result = mModule->mBfIRBuilder->CreateCall(bindFuncVal, irArgs);
-		auto destCallingConv = mModule->GetCallingConvention(bindMethodInstance->GetOwner(), bindMethodInstance->mMethodDef);
+		auto destCallingConv = mModule->GetIRCallingConvention(bindMethodInstance);
 		if (destCallingConv != BfIRCallingConv_CDecl)
 		if (destCallingConv != BfIRCallingConv_CDecl)
 			mModule->mBfIRBuilder->SetCallCallingConv(result, destCallingConv);
 			mModule->mBfIRBuilder->SetCallCallingConv(result, destCallingConv);
 		if (methodInstance->mReturnType->IsValuelessType())
 		if (methodInstance->mReturnType->IsValuelessType())
@@ -9942,6 +9942,8 @@ BfLambdaInstance* BfExprEvaluator::GetLambdaInstance(BfLambdaBindExpression* lam
 						capturedType = mModule->CreateRefType(capturedType);
 						capturedType = mModule->CreateRefType(capturedType);
 					}
 					}
 					
 					
+					if (captureType == BfCaptureType_Reference)
+						capturedEntry.mExplicitlyByReference = true;
 					capturedEntry.mType = capturedType;
 					capturedEntry.mType = capturedType;
 					if (outerLocal->mName == "this")
 					if (outerLocal->mName == "this")
 						capturedEntry.mName = "__this";
 						capturedEntry.mName = "__this";
@@ -10208,6 +10210,7 @@ BfLambdaInstance* BfExprEvaluator::GetLambdaInstance(BfLambdaBindExpression* lam
 	lambdaInstance->mClosureTypeInstance = closureTypeInst;
 	lambdaInstance->mClosureTypeInstance = closureTypeInst;
 	lambdaInstance->mOuterClosure = outerClosure;
 	lambdaInstance->mOuterClosure = outerClosure;
 	lambdaInstance->mCopyOuterCaptures = copyOuterCaptures;
 	lambdaInstance->mCopyOuterCaptures = copyOuterCaptures;
+	lambdaInstance->mDeclaringMethodIsMutating = mModule->mCurMethodInstance->mMethodDef->mIsMutating;
 	lambdaInstance->mIsStatic = methodDef->mIsStatic;
 	lambdaInstance->mIsStatic = methodDef->mIsStatic;
 	lambdaInstance->mClosureFunc = closureFunc;	
 	lambdaInstance->mClosureFunc = closureFunc;	
 	lambdaInstance->mMethodInstance = methodInstance;
 	lambdaInstance->mMethodInstance = methodInstance;

+ 4 - 2
IDEHelper/Compiler/BfMangler.cpp

@@ -2024,10 +2024,12 @@ void BfMSMangler::Mangle(StringImpl& name, bool is64Bit, BfMethodInstance* metho
 		name += qualifier;
 		name += qualifier;
 	}	
 	}	
 
 
+	auto callingConvention = mangleContext.mModule->GetIRCallingConvention(typeInst, methodDef);
+
 	char callingConv = 'A';
 	char callingConv = 'A';
-	if (methodDef->mCallingConvention == BfCallingConvention_Stdcall)
+	if (callingConvention == BfIRCallingConv_StdCall)
 		callingConv = 'G';
 		callingConv = 'G';
-	else if ((!mangleContext.mIs64Bit) && (!methodDef->mIsStatic))
+	else if (callingConvention == BfIRCallingConv_ThisCall)
 		callingConv = 'E';
 		callingConv = 'E';
 	name += callingConv;
 	name += callingConv;
 
 

+ 30 - 16
IDEHelper/Compiler/BfModule.cpp

@@ -3712,7 +3712,7 @@ void BfModule::EmitEquals(BfTypedValue leftValue, BfTypedValue rightValue, BfIRB
 	exprEvaluator.mExpectingType = mCurMethodInstance->mReturnType;
 	exprEvaluator.mExpectingType = mCurMethodInstance->mReturnType;
 	exprEvaluator.PerformBinaryOperation((BfAstNode*)NULL, (BfAstNode*)NULL, BfBinaryOp_Equality, NULL, BfBinOpFlag_None, leftValue, rightValue);
 	exprEvaluator.PerformBinaryOperation((BfAstNode*)NULL, (BfAstNode*)NULL, BfBinaryOp_Equality, NULL, BfBinOpFlag_None, leftValue, rightValue);
 	BfTypedValue result = exprEvaluator.GetResult();
 	BfTypedValue result = exprEvaluator.GetResult();
-	if (result)
+	if ((result) && (!result.mType->IsVar()))
 	{
 	{
 		auto nextBB = mBfIRBuilder->CreateBlock("next");
 		auto nextBB = mBfIRBuilder->CreateBlock("next");
 		mBfIRBuilder->CreateCondBr(result.mValue, nextBB, exitBB);
 		mBfIRBuilder->CreateCondBr(result.mValue, nextBB, exitBB);
@@ -5676,6 +5676,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
 			MethodFlags_Virtual = 0x40,
 			MethodFlags_Virtual = 0x40,
 			MethodFlags_StdCall = 0x1000,
 			MethodFlags_StdCall = 0x1000,
 			MethodFlags_FastCall = 0x2000,
 			MethodFlags_FastCall = 0x2000,
+			MethodFlags_ThisCall = 0x3000,
 			MethodFlags_Mutating = 0x4000,
 			MethodFlags_Mutating = 0x4000,
 		};
 		};
 
 
@@ -5693,6 +5694,12 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
 			methodFlags = (MethodFlags)(methodFlags | MethodFlags_FastCall);
 			methodFlags = (MethodFlags)(methodFlags | MethodFlags_FastCall);
 		if (methodDef->mIsMutating)
 		if (methodDef->mIsMutating)
 			methodFlags = (MethodFlags)(methodFlags | MethodFlags_Mutating);
 			methodFlags = (MethodFlags)(methodFlags | MethodFlags_Mutating);
+
+		auto callingConvention = GetIRCallingConvention(defaultMethod);
+		if (callingConvention == BfIRCallingConv_ThisCall)
+			methodFlags = (MethodFlags)(methodFlags | MethodFlags_ThisCall);
+		else if (callingConvention == BfIRCallingConv_StdCall)
+			methodFlags = (MethodFlags)(methodFlags | MethodFlags_StdCall);
 		
 		
 		int customAttrIdx = _HandleCustomAttrs(methodCustomAttributes);
 		int customAttrIdx = _HandleCustomAttrs(methodCustomAttributes);
 
 
@@ -8794,7 +8801,7 @@ BfIRValue BfModule::CreateFunctionFrom(BfMethodInstance* methodInstance, bool tr
 	auto funcType = mBfIRBuilder->CreateFunctionType(returnType, paramTypes);
 	auto funcType = mBfIRBuilder->CreateFunctionType(returnType, paramTypes);
 
 
 	auto func = mBfIRBuilder->CreateFunction(funcType, BfIRLinkageType_External, methodName);
 	auto func = mBfIRBuilder->CreateFunction(funcType, BfIRLinkageType_External, methodName);
-	auto callingConv = GetCallingConvention(methodInstance->GetOwner(), methodDef);
+	auto callingConv = GetIRCallingConvention(methodInstance);
 	if (callingConv != BfIRCallingConv_CDecl)
 	if (callingConv != BfIRCallingConv_CDecl)
 		mBfIRBuilder->SetFuncCallingConv(func, callingConv);
 		mBfIRBuilder->SetFuncCallingConv(func, callingConv);
 	SetupIRMethod(methodInstance, func, isInlined);
 	SetupIRMethod(methodInstance, func, isInlined);
@@ -13020,7 +13027,7 @@ void BfModule::CreateDelegateInvokeMethod()
 	BfIRValue nonStaticResult;
 	BfIRValue nonStaticResult;
 	BfIRValue staticResult;
 	BfIRValue staticResult;
 
 
-	auto callingConv = GetCallingConvention(mCurTypeInstance, mCurMethodInstance->mMethodDef);
+	auto callingConv = GetIRCallingConvention(mCurTypeInstance, mCurMethodInstance->mMethodDef);
 
 
 	/// Non-static invocation
 	/// Non-static invocation
 	{	
 	{	
@@ -13540,7 +13547,7 @@ void BfModule::EmitDtorBody()
 		auto basePtr = mBfIRBuilder->CreateBitCast(thisVal.mValue, mBfIRBuilder->MapTypeInstPtr(mContext->mBfObjectType));
 		auto basePtr = mBfIRBuilder->CreateBitCast(thisVal.mValue, mBfIRBuilder->MapTypeInstPtr(mContext->mBfObjectType));
 		SizedArray<BfIRValue, 1> vals = { basePtr };
 		SizedArray<BfIRValue, 1> vals = { basePtr };
 		result = mBfIRBuilder->CreateCall(dtorFunc.mFunc, vals);
 		result = mBfIRBuilder->CreateCall(dtorFunc.mFunc, vals);
-		mBfIRBuilder->SetCallCallingConv(result, GetCallingConvention(dtorFunc.mMethodInstance));
+		mBfIRBuilder->SetCallCallingConv(result, GetIRCallingConvention(dtorFunc.mMethodInstance));
 		mBfIRBuilder->SetTailCall(result);		
 		mBfIRBuilder->SetTailCall(result);		
 
 
 		return;		
 		return;		
@@ -13705,7 +13712,7 @@ void BfModule::EmitDtorBody()
 							auto basePtr = mBfIRBuilder->CreateBitCast(mCurMethodState->mLocals[0]->mValue, mBfIRBuilder->MapTypeInstPtr(checkBaseType));
 							auto basePtr = mBfIRBuilder->CreateBitCast(mCurMethodState->mLocals[0]->mValue, mBfIRBuilder->MapTypeInstPtr(checkBaseType));
 							SizedArray<BfIRValue, 1> vals = { basePtr };
 							SizedArray<BfIRValue, 1> vals = { basePtr };
 							auto callInst = mBfIRBuilder->CreateCall(dtorMethodInstance.mFunc, vals);
 							auto callInst = mBfIRBuilder->CreateCall(dtorMethodInstance.mFunc, vals);
-							mBfIRBuilder->SetCallCallingConv(callInst, GetCallingConvention(dtorMethodInstance.mMethodInstance));
+							mBfIRBuilder->SetCallCallingConv(callInst, GetIRCallingConvention(dtorMethodInstance.mMethodInstance));
 						}
 						}
 					}
 					}
 					else
 					else
@@ -13851,7 +13858,7 @@ void BfModule::CreateDllImportMethod()
 		mBfIRBuilder->CreateCall(loadSharedLibsFunc, SizedArray<BfIRValue, 0>());
 		mBfIRBuilder->CreateCall(loadSharedLibsFunc, SizedArray<BfIRValue, 0>());
 	}
 	}
 
 
-	auto callingConvention = GetCallingConvention(mCurTypeInstance, mCurMethodInstance->mMethodDef);
+	auto callingConvention = GetIRCallingConvention(mCurTypeInstance, mCurMethodInstance->mMethodDef);
 
 
 	BfIRType returnType;
 	BfIRType returnType;
 	SizedArray<BfIRType, 8> paramTypes;
 	SizedArray<BfIRType, 8> paramTypes;
@@ -13887,7 +13894,7 @@ void BfModule::CreateDllImportMethod()
 	}
 	}
 }
 }
 
 
-BfIRCallingConv BfModule::GetCallingConvention(BfTypeInstance* typeInst, BfMethodDef* methodDef)
+BfIRCallingConv BfModule::GetIRCallingConvention(BfTypeInstance* typeInst, BfMethodDef* methodDef)
 {
 {
 	if ((mCompiler->mOptions.mMachineType != BfMachineType_x86) || (mCompiler->mOptions.mPlatformType != BfPlatformType_Windows))
 	if ((mCompiler->mOptions.mMachineType != BfMachineType_x86) || (mCompiler->mOptions.mPlatformType != BfPlatformType_Windows))
 		return BfIRCallingConv_CDecl;			
 		return BfIRCallingConv_CDecl;			
@@ -13899,9 +13906,15 @@ BfIRCallingConv BfModule::GetCallingConvention(BfTypeInstance* typeInst, BfMetho
 	return BfIRCallingConv_CDecl;
 	return BfIRCallingConv_CDecl;
 }
 }
 
 
-BfIRCallingConv BfModule::GetCallingConvention(BfMethodInstance* methodInstance)
+BfIRCallingConv BfModule::GetIRCallingConvention(BfMethodInstance* methodInstance)
 {
 {
-	return GetCallingConvention(methodInstance->GetOwner(), methodInstance->mMethodDef);
+	auto methodDef = methodInstance->mMethodDef;
+	BfTypeInstance* owner = NULL;
+	if (!methodDef->mIsStatic)
+		owner = methodInstance->GetParamType(-1)->ToTypeInstance();
+	if (owner == NULL)
+		owner = methodInstance->GetOwner();
+	return GetIRCallingConvention(owner, methodInstance->mMethodDef);
 }
 }
 
 
 void BfModule::SetupIRMethod(BfMethodInstance* methodInstance, BfIRFunction func, bool isInlined)
 void BfModule::SetupIRMethod(BfMethodInstance* methodInstance, BfIRFunction func, bool isInlined)
@@ -13926,7 +13939,7 @@ void BfModule::SetupIRMethod(BfMethodInstance* methodInstance, BfIRFunction func
 		mBfIRBuilder->Func_AddAttribute(func, -1, BFIRAttribute_DllExport);
 		mBfIRBuilder->Func_AddAttribute(func, -1, BFIRAttribute_DllExport);
 	if (methodDef->mNoReturn)
 	if (methodDef->mNoReturn)
 		mBfIRBuilder->Func_AddAttribute(func, -1, BfIRAttribute_NoReturn);
 		mBfIRBuilder->Func_AddAttribute(func, -1, BfIRAttribute_NoReturn);
-	auto callingConv = GetCallingConvention(methodInstance->GetOwner(), methodDef);
+	auto callingConv = GetIRCallingConvention(methodInstance);
 	if (callingConv != BfIRCallingConv_CDecl)
 	if (callingConv != BfIRCallingConv_CDecl)
 		mBfIRBuilder->SetFuncCallingConv(func, callingConv);
 		mBfIRBuilder->SetFuncCallingConv(func, callingConv);
 	
 	
@@ -14401,7 +14414,7 @@ void BfModule::EmitCtorBody(bool& skipBody)
 								}
 								}
 								AddCallDependency(ctorBodyMethodInstance.mMethodInstance, true);
 								AddCallDependency(ctorBodyMethodInstance.mMethodInstance, true);
 								auto callInst = mBfIRBuilder->CreateCall(ctorBodyMethodInstance.mFunc, args);
 								auto callInst = mBfIRBuilder->CreateCall(ctorBodyMethodInstance.mFunc, args);
-								auto callingConv = GetCallingConvention(ctorBodyMethodInstance.mMethodInstance->GetOwner(), ctorBodyMethodInstance.mMethodInstance->mMethodDef);
+								auto callingConv = GetIRCallingConvention(ctorBodyMethodInstance.mMethodInstance);
 								if (callingConv != BfIRCallingConv_CDecl)
 								if (callingConv != BfIRCallingConv_CDecl)
 									mBfIRBuilder->SetCallCallingConv(callInst, callingConv);
 									mBfIRBuilder->SetCallCallingConv(callInst, callingConv);
 // 								if (!mCurTypeInstance->mBaseType->IsValuelessType())
 // 								if (!mCurTypeInstance->mBaseType->IsValuelessType())
@@ -15288,6 +15301,7 @@ void BfModule::ProcessMethod_ProcessDeferredLocals(int startIdx)
 			else
 			else
 				closureState.mClosureType = lambdaInstance->mDelegateTypeInstance;
 				closureState.mClosureType = lambdaInstance->mDelegateTypeInstance;
 			closureState.mClosureInstanceInfo = lambdaInstance->mMethodInstance->mMethodInfoEx->mClosureInstanceInfo;
 			closureState.mClosureInstanceInfo = lambdaInstance->mMethodInstance->mMethodInfoEx->mClosureInstanceInfo;
+			closureState.mDeclaringMethodIsMutating = lambdaInstance->mDeclaringMethodIsMutating;
 			mCurMethodState->mMixinState = lambdaInstance->mDeclMixinState;
 			mCurMethodState->mMixinState = lambdaInstance->mDeclMixinState;
 
 
 			_ClearState();
 			_ClearState();
@@ -16255,7 +16269,7 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup)
 	bool isTypedPrimitiveFunc = mCurTypeInstance->IsTypedPrimitive() && (methodDef->mMethodType != BfMethodType_Ctor);
 	bool isTypedPrimitiveFunc = mCurTypeInstance->IsTypedPrimitive() && (methodDef->mMethodType != BfMethodType_Ctor);
 	int irParamCount = methodInstance->GetIRFunctionParamCount(this);
 	int irParamCount = methodInstance->GetIRFunctionParamCount(this);
 
 
-	if (methodDef->mImportKind != BfImportKind_Dynamic)
+	if (methodInstance->GetImportKind() != BfImportKind_Import_Dynamic)
 	{
 	{
 		int localIdx = 0;
 		int localIdx = 0;
 		int argIdx = 0;				
 		int argIdx = 0;				
@@ -16823,7 +16837,7 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup)
 	bool skipBody = false;
 	bool skipBody = false;
 	bool skipUpdateSrcPos = false;
 	bool skipUpdateSrcPos = false;
 	bool skipEndChecks = false;
 	bool skipEndChecks = false;
-	bool hasExternSpecifier = (methodDeclaration != NULL) && (methodDeclaration->mExternSpecifier != NULL) && (methodDef->mImportKind != BfImportKind_Dynamic);
+	bool hasExternSpecifier = (methodDeclaration != NULL) && (methodDeclaration->mExternSpecifier != NULL) && (methodInstance->GetImportKind() != BfImportKind_Import_Dynamic);
 	auto propertyDeclaration = methodDef->GetPropertyDeclaration();
 	auto propertyDeclaration = methodDef->GetPropertyDeclaration();
 
 
 	if ((methodDef != NULL) && (propertyDeclaration != NULL) && (propertyDeclaration->mExternSpecifier != NULL))
 	if ((methodDef != NULL) && (propertyDeclaration != NULL) && (propertyDeclaration->mExternSpecifier != NULL))
@@ -16986,7 +17000,7 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup)
 		}
 		}
 
 
 		bool isDllImport = false;		
 		bool isDllImport = false;		
-		if (methodDef->mImportKind == BfImportKind_Static)
+		if (methodInstance->GetImportKind() == BfImportKind_Import_Static)
 		{
 		{
 			for (auto customAttr : methodInstance->GetCustomAttributes()->mAttributes)
 			for (auto customAttr : methodInstance->GetCustomAttributes()->mAttributes)
 			{
 			{
@@ -17015,7 +17029,7 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup)
 
 
 			//mImportFileNames
 			//mImportFileNames
 		}
 		}
-		else if (methodDef->mImportKind == BfImportKind_Dynamic)
+		else if (methodInstance->GetImportKind() == BfImportKind_Import_Dynamic)
 		{
 		{
 			CreateDllImportMethod();
 			CreateDllImportMethod();
 		}
 		}
@@ -17534,7 +17548,7 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup)
 			CreateFakeCallerMethod(mangledName);
 			CreateFakeCallerMethod(mangledName);
 		mBfIRBuilder->Func_DeleteBody(mCurMethodInstance->mIRFunction);
 		mBfIRBuilder->Func_DeleteBody(mCurMethodInstance->mIRFunction);
 	}
 	}
-	else if ((methodDef->mImportKind == BfImportKind_Dynamic) && (!mCompiler->IsHotCompile()))
+	else if ((methodInstance->GetImportKind() == BfImportKind_Import_Dynamic) && (!mCompiler->IsHotCompile()))
 	{
 	{
 		// We only need the DLL stub when we may be hot swapping
 		// We only need the DLL stub when we may be hot swapping
 		mBfIRBuilder->Func_DeleteBody(mCurMethodInstance->mIRFunction);
 		mBfIRBuilder->Func_DeleteBody(mCurMethodInstance->mIRFunction);

+ 4 - 2
IDEHelper/Compiler/BfModule.h

@@ -813,6 +813,7 @@ public:
 	BfIRValue mClosureFunc;
 	BfIRValue mClosureFunc;
 	BfIRValue mDtorFunc;
 	BfIRValue mDtorFunc;
 	bool mCopyOuterCaptures;
 	bool mCopyOuterCaptures;
+	bool mDeclaringMethodIsMutating;
 	bool mIsStatic;
 	bool mIsStatic;
 	Array<BfLambdaCaptureInfo> mCaptures;
 	Array<BfLambdaCaptureInfo> mCaptures;
 	BfMethodInstance* mMethodInstance;
 	BfMethodInstance* mMethodInstance;
@@ -829,6 +830,7 @@ public:
 		mDeclMixinState = NULL;
 		mDeclMixinState = NULL;
 		mOuterClosure = NULL;
 		mOuterClosure = NULL;
 		mCopyOuterCaptures = false;
 		mCopyOuterCaptures = false;
+		mDeclaringMethodIsMutating = false;
 		mIsStatic = false;
 		mIsStatic = false;
 		mMethodInstance = NULL;
 		mMethodInstance = NULL;
 		mDtorMethodInstance = NULL;
 		mDtorMethodInstance = NULL;
@@ -1722,8 +1724,8 @@ public:
 	void CreateStaticCtor();	
 	void CreateStaticCtor();	
 	BfIRValue CreateDllImportGlobalVar(BfMethodInstance* methodInstance, bool define = false);
 	BfIRValue CreateDllImportGlobalVar(BfMethodInstance* methodInstance, bool define = false);
 	void CreateDllImportMethod();			
 	void CreateDllImportMethod();			
-	BfIRCallingConv GetCallingConvention(BfTypeInstance* typeInst, BfMethodDef* methodDef);
-	BfIRCallingConv GetCallingConvention(BfMethodInstance* methodInstance);
+	BfIRCallingConv GetIRCallingConvention(BfTypeInstance* typeInst, BfMethodDef* methodDef);
+	BfIRCallingConv GetIRCallingConvention(BfMethodInstance* methodInstance);
 	void SetupIRMethod(BfMethodInstance* methodInstance, BfIRFunction func, bool isInlined);
 	void SetupIRMethod(BfMethodInstance* methodInstance, BfIRFunction func, bool isInlined);
 	void EmitCtorBody(bool& skipBody);
 	void EmitCtorBody(bool& skipBody);
 	void EmitDtorBody();
 	void EmitDtorBody();

+ 18 - 1
IDEHelper/Compiler/BfResolvedTypeUtils.cpp

@@ -497,6 +497,23 @@ BfMethodInstance::~BfMethodInstance()
 	delete mMethodInfoEx;
 	delete mMethodInfoEx;
 }
 }
 
 
+BfImportKind BfMethodInstance::GetImportKind()
+{
+	if (mMethodDef->mImportKind != BfImportKind_Import_Unknown)
+		return mMethodDef->mImportKind;
+
+	auto module = GetOwner()->mModule;
+	BfCustomAttribute* customAttribute = GetCustomAttributes()->Get(module->mCompiler->mImportAttributeTypeDef);
+	if (customAttribute == NULL)
+		return BfImportKind_Import_Static;
+
+	BfIRConstHolder* constHolder = GetOwner()->mConstHolder;
+	String* filePath = module->GetStringPoolString(customAttribute->mCtorArgs[0], constHolder);
+	if (filePath == NULL)
+		return BfImportKind_Import_Static;
+	return BfMethodDef::GetImportKindFromPath(*filePath);
+}
+
 void BfMethodInstance::UndoDeclaration(bool keepIRFunction)
 void BfMethodInstance::UndoDeclaration(bool keepIRFunction)
 {	
 {	
 	
 	
@@ -614,7 +631,7 @@ bool BfMethodInstance::AlwaysInline()
 
 
 BfImportCallKind BfMethodInstance::GetImportCallKind()
 BfImportCallKind BfMethodInstance::GetImportCallKind()
 {
 {
-	if (mMethodDef->mImportKind != BfImportKind_Dynamic)
+	if (GetImportKind() != BfImportKind_Import_Dynamic)
 		return BfImportCallKind_None;	
 		return BfImportCallKind_None;	
 	if ((mHotMethod != NULL) && ((mHotMethod->mFlags & BfHotDepDataFlag_IsOriginalBuild) == 0))
 	if ((mHotMethod != NULL) && ((mHotMethod->mFlags & BfHotDepDataFlag_IsOriginalBuild) == 0))
 		return BfImportCallKind_GlobalVar_Hot;
 		return BfImportCallKind_GlobalVar_Hot;

+ 2 - 2
IDEHelper/Compiler/BfResolvedTypeUtils.h

@@ -797,14 +797,14 @@ public:
 		return mMethodDef->mMethodType == BfMethodType_Mixin;
 		return mMethodDef->mMethodType == BfMethodType_Mixin;
 	}
 	}
 
 
+	BfImportKind GetImportKind();
 	void UndoDeclaration(bool keepIRFunction = false);
 	void UndoDeclaration(bool keepIRFunction = false);
 	BfTypeInstance* GetOwner();	
 	BfTypeInstance* GetOwner();	
 	BfModule* GetModule();
 	BfModule* GetModule();
 	bool IsSpecializedGenericMethod();
 	bool IsSpecializedGenericMethod();
 	bool IsSpecializedGenericMethodOrType();
 	bool IsSpecializedGenericMethodOrType();
 	bool IsSpecializedByAutoCompleteMethod();
 	bool IsSpecializedByAutoCompleteMethod();
-	bool HasThis();
-	bool WantsThisPointer();
+	bool HasThis();	
 	bool HasParamsArray();
 	bool HasParamsArray();
 	bool HasStructRet();
 	bool HasStructRet();
 	bool HasSelf();
 	bool HasSelf();

+ 13 - 0
IDEHelper/Compiler/BfSystem.cpp

@@ -453,6 +453,19 @@ BfMethodDef::~BfMethodDef()
 	FreeMembers();
 	FreeMembers();
 }
 }
 
 
+BfImportKind BfMethodDef::GetImportKindFromPath(const StringImpl& filePath)
+{
+	String fileExt = GetFileExtension(filePath);
+
+	if ((fileExt.Equals(".DLL", StringImpl::CompareKind_OrdinalIgnoreCase)) ||
+		(fileExt.Equals(".EXE", StringImpl::CompareKind_OrdinalIgnoreCase)))
+	{
+		return BfImportKind_Import_Dynamic;
+	}
+
+	return BfImportKind_Import_Static;
+}
+
 void BfMethodDef::Reset()
 void BfMethodDef::Reset()
 {
 {
 	FreeMembers();
 	FreeMembers();

+ 4 - 2
IDEHelper/Compiler/BfSystem.h

@@ -664,8 +664,9 @@ enum BfOptimize : int8
 enum BfImportKind : int8
 enum BfImportKind : int8
 {
 {
 	BfImportKind_None,
 	BfImportKind_None,
-	BfImportKind_Static,
-	BfImportKind_Dynamic,
+	BfImportKind_Import_Unknown,
+	BfImportKind_Import_Dynamic,
+	BfImportKind_Import_Static,
 	BfImportKind_Export
 	BfImportKind_Export
 };
 };
 
 
@@ -758,6 +759,7 @@ public:
 
 
 	virtual ~BfMethodDef();
 	virtual ~BfMethodDef();
 
 
+	static BfImportKind GetImportKindFromPath(const StringImpl& filePath);
 	bool HasNoThisSplat() { return mIsMutating || mNoSplat; }
 	bool HasNoThisSplat() { return mIsMutating || mNoSplat; }
 	void Reset();
 	void Reset();
 	void FreeMembers();
 	void FreeMembers();