@@ -918,33 +918,43 @@ class Savi::Compiler::CodeGen
918918 param_count = llvm_func.params.size
919919 args = param_count.times.map { |i | llvm_func.params[i] }.to_a
920920
921- value = gen_ffi_call(gfunc, args)
921+ value = gen_ffi_call(gfunc, args, llvm_func.function_type.return_type )
922922
923923 gen_return_value(value, nil )
924924
925925 gen_func_end(gfunc)
926926 end
927927
928- def gen_ffi_call (gfunc, args)
928+ def gen_ffi_call (gfunc, args, cast_to_ret_type )
929929 llvm_ffi_func = gen_ffi_decl(gfunc)
930+ function_type = llvm_ffi_func.function_type
931+
932+ # Cast arguments to their corresponding parameter types (if necessary).
933+ cast_args = args.map_with_index { |arg , index |
934+ if index < function_type.params_types.size
935+ arg = gen_force_cast(arg, function_type.params_types[index])
936+ end
937+ arg
938+ }
930939
931940 # Now call the FFI function, according to its convention.
932941 case gfunc.calling_convention
933942 when GenFunc ::Simple
934943 value = @builder .call(
935- llvm_ffi_func. function_type,
944+ function_type,
936945 llvm_ffi_func,
937- args ,
946+ cast_args ,
938947 )
939948 value = gen_none if llvm_ffi_func.ret_type == @void
940- value
949+ value = gen_force_cast(value, cast_to_ret_type)
950+
941951 when GenFunc ::Errorable
942952 then_block = gen_block(" invoke_then" )
943953 else_block = gen_block(" invoke_else" )
944954 value = @builder .invoke(
945- llvm_ffi_func. function_type,
955+ function_type,
946956 llvm_ffi_func,
947- args ,
957+ cast_args ,
948958 then_block,
949959 else_block,
950960 )
@@ -2197,7 +2207,7 @@ class Savi::Compiler::CodeGen
21972207 while args.size > cast_args.size
21982208 cast_args << args[cast_args.size]
21992209 end
2200- return gen_ffi_call(is_ffi_gfunc, cast_args)
2210+ return gen_ffi_call(is_ffi_gfunc, cast_args, llvm_type_of(signature.ret) )
22012211 end
22022212
22032213 @builder .call(llvm_func_type, func, cast_args)
@@ -4053,6 +4063,17 @@ class Savi::Compiler::CodeGen
40534063 end
40544064 end
40554065
4066+ def gen_force_cast (value : LLVM ::Value , to_type : LLVM ::Type )
4067+ if value.type == to_type
4068+ value
4069+ elsif value.type.kind == LLVM ::Type ::Kind ::Struct \
4070+ || to_type.kind == LLVM ::Type ::Kind ::Struct
4071+ gen_struct_bit_cast(value, to_type)
4072+ else
4073+ @builder .bit_cast(value, to_type)
4074+ end
4075+ end
4076+
40564077 def gen_struct_bit_cast (value : LLVM ::Value , to_type : LLVM ::Type )
40574078 # LLVM doesn't allow directly casting to/from structs, so we cheat a bit
40584079 # with an alloca in between the two as a pointer that we can cast.
0 commit comments