Răsfoiți Sursa

Sized-array calling convention fix

Brian Fiete 4 ani în urmă
părinte
comite
8a63a7ed80

+ 1 - 1
IDEHelper/Backend/BeIRCodeGen.cpp

@@ -2400,7 +2400,7 @@ void BeIRCodeGen::HandleNextCmd()
 						callInst->mArgs[argIdx - 1].mByRefSize = arg;
 						if (auto func = BeValueDynCast<BeFunction>(callInst->mFunc))
 						{
-							BF_ASSERT(func->mParams[argIdx - 1].mByValSize == arg);
+							BF_ASSERT((func->mParams[argIdx - 1].mByValSize == arg) || (func->mParams[argIdx - 1].mByValSize == -1));
 						}
 					}
 					else

+ 2 - 2
IDEHelper/Compiler/BfExprEvaluator.cpp

@@ -5371,9 +5371,9 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance*
 							mModule->mBfIRBuilder->Call_AddAttribute(callInst, argIdx + 1, BfIRAttribute_NoCapture);
 							addDeref = paramType->mSize;
 						}
-						else if (methodInstance->WantsStructsAttribByVal())
+						else if ((methodInstance->WantsStructsAttribByVal()) && (!paramType->IsSizedArray()))
 						{
-							mModule->mBfIRBuilder->Call_AddAttribute(callInst, argIdx + 1, BfIRAttribute_ByVal, mModule->mSystem->mPtrSize);
+							mModule->mBfIRBuilder->Call_AddAttribute(callInst, argIdx + 1, BfIRAttribute_ByVal, paramType->mAlign);
 						}
 					}
 				}

+ 3 - 2
IDEHelper/Compiler/BfModule.cpp

@@ -15676,10 +15676,11 @@ void BfModule::SetupIRMethod(BfMethodInstance* methodInstance, BfIRFunction func
 					PopulateType(resolvedTypeRef, BfPopulateType_Data);
 					addDeref = resolvedTypeRef->mSize;
 				}
-				else if (methodInstance->WantsStructsAttribByVal())
+				else if ((methodInstance->WantsStructsAttribByVal()) && (!resolvedTypeRef->IsSizedArray()))
 				{
 					mBfIRBuilder->PopulateType(resolvedTypeRef);
-					mBfIRBuilder->Func_AddAttribute(func, argIdx + 1, BfIRAttribute_ByVal, mSystem->mPtrSize);
+					BF_ASSERT(resolvedTypeRef->mAlign > 0);
+					mBfIRBuilder->Func_AddAttribute(func, argIdx + 1, BfIRAttribute_ByVal, resolvedTypeRef->mAlign);
 				}
 			}
 			else if (resolvedTypeRef->IsPrimitiveType())

+ 5 - 0
IDEHelper/Tests/CLib/main.cpp

@@ -534,6 +534,11 @@ extern "C" Interop::StructJ Func4J(Interop::StructJ arg0, Interop::StructJ arg1,
 	return ret;
 }
 
+extern "C" double Func5(float v0[2], float v1[3])
+{
+	return v0[0] + v0[1]*10 + v1[0]*100 + v1[1]*1000 + v1[2]*10000;
+}
+
 void UseIt()
 {
 	Interop::StructA sa;

+ 6 - 0
IDEHelper/Tests/src/Interop.bf

@@ -308,6 +308,9 @@ namespace Tests
 		[LinkName(.C)]
 		public static extern StructJ Func4J(StructJ arg0, StructJ arg1, StructJ arg2, StructJ arg3);
 
+		[LinkName(.C)]
+		public static extern  double Func5(float[2] v0, float[3] v1);
+
 		static int32 LocalFunc0K(int32 a, StructK b) => a + (int32)b.mX * 100 + (int32)b.mY * 10000;
 		static int32 LocalFunc0L(int32 a, StructL b) => a + (int32)b.mX * 100 + (int32)b.mY * 10000;
 		static int32 LocalFunc0M(int32 a, StructM b) => a + (int32)b.mX * 100 + (int32)b.mY * 10000;
@@ -517,6 +520,9 @@ namespace Tests
 			sj3.mLength = 6;
 			var sjRet = Func4J(sj0, sj1, sj2, sj3);
 			Test.Assert(sjRet.mLength == 6050403);
+
+			var val5 = Func5(.(1, 2), .(3, 4, 5));
+			Test.Assert(Math.Round(val5) == 54321);
 		}
 	}
 }