@@ -6723,125 +6723,149 @@ fn decl_native_fn_and_pair(@crate_ctxt ccx,
6723
6723
// that allows types of different sizes to be returned.
6724
6724
auto rty_is_nil = ty. type_is_nil( ccx. tcx, ty. ty_fn_ret( ccx. tcx, fn_type) ) ;
6725
6725
6726
- let vec[ ValueRef ] call_args = vec( ) ;
6727
- auto arg_n = 3 u;
6728
6726
auto pass_task;
6729
-
6730
- auto lltaskptr = vp2i( bcx, fcx. lltaskptr) ;
6727
+ auto cast_to_i32;
6731
6728
alt ( abi) {
6732
6729
case ( ast. native_abi_rust) {
6733
6730
pass_task = true ;
6734
- call_args += vec( lltaskptr) ;
6735
- for each ( uint i in _uint. range( 0 u, num_ty_param) ) {
6736
- auto llarg = llvm. LLVMGetParam ( fcx. llfn, arg_n) ;
6737
- fcx. lltydescs += vec( llarg) ;
6738
- assert ( llarg as int != 0 ) ;
6739
- call_args += vec( vp2i( bcx, llarg) ) ;
6740
- arg_n += 1 u;
6741
- }
6731
+ cast_to_i32 = true ;
6742
6732
}
6743
6733
case ( ast. native_abi_rust_intrinsic) {
6744
6734
pass_task = true ;
6745
- call_args += vec ( lltaskptr ) ;
6735
+ cast_to_i32 = false ;
6746
6736
}
6747
6737
case ( ast. native_abi_cdecl) {
6748
6738
pass_task = false ;
6739
+ cast_to_i32 = true ;
6749
6740
}
6750
6741
case ( ast. native_abi_llvm) {
6751
6742
pass_task = false ;
6752
- // We handle this case below.
6743
+ cast_to_i32 = false ;
6744
+ }
6745
+ }
6746
+
6747
+ auto lltaskptr;
6748
+ if ( cast_to_i32) {
6749
+ lltaskptr = vp2i( bcx, fcx. lltaskptr) ;
6750
+ } else {
6751
+ lltaskptr = fcx. lltaskptr;
6752
+ }
6753
+
6754
+ let vec[ ValueRef ] call_args = vec( ) ;
6755
+ if ( pass_task) { call_args += vec( lltaskptr) ; }
6756
+
6757
+ auto arg_n = 3 u;
6758
+ for each ( uint i in _uint. range( 0 u, num_ty_param) ) {
6759
+ auto llarg = llvm. LLVMGetParam ( fcx. llfn, arg_n) ;
6760
+ fcx. lltydescs += vec( llarg) ;
6761
+ assert ( llarg as int != 0 ) ;
6762
+
6763
+ if ( cast_to_i32) {
6764
+ call_args += vec( vp2i( bcx, llarg) ) ;
6765
+ } else {
6766
+ call_args += vec( llarg) ;
6753
6767
}
6768
+
6769
+ arg_n += 1 u;
6754
6770
}
6755
6771
6756
- fn push_arg( @block_ctxt cx,
6757
- & mutable vec[ ValueRef ] args,
6758
- ValueRef v,
6759
- ty. t t,
6760
- ast. mode mode) {
6772
+ fn convert_arg_to_i32( @block_ctxt cx,
6773
+ ValueRef v,
6774
+ ty. t t,
6775
+ ast. mode mode) -> ValueRef {
6761
6776
if ( mode == ast. val) {
6762
6777
if ( ty. type_is_integral( cx. fcx. lcx. ccx. tcx, t) ) {
6763
6778
auto lldsttype = T_int ( ) ;
6764
6779
auto llsrctype = type_of( cx. fcx. lcx. ccx, t) ;
6765
6780
if ( llvm. LLVMGetIntTypeWidth ( lldsttype) >
6766
6781
llvm. LLVMGetIntTypeWidth ( llsrctype) ) {
6767
- args += vec( cx. build. ZExtOrBitCast ( v, T_int ( ) ) ) ;
6768
- } else {
6769
- args += vec( cx. build. TruncOrBitCast ( v, T_int ( ) ) ) ;
6782
+ ret cx. build. ZExtOrBitCast ( v, T_int( ) ) ;
6770
6783
}
6771
- ret;
6784
+ ret cx . build . TruncOrBitCast ( v , T_int ( ) ) ;
6772
6785
}
6773
6786
if ( ty. type_is_fp( cx. fcx. lcx. ccx. tcx, t) ) {
6774
- args += vec( cx. build. FPToSI ( v, T_int ( ) ) ) ;
6775
- ret;
6787
+ ret cx. build. FPToSI ( v, T_int ( ) ) ;
6776
6788
}
6777
6789
}
6778
6790
6779
- args += vec ( vp2i( cx, v) ) ;
6791
+ ret vp2i( cx, v) ;
6780
6792
}
6781
6793
6782
6794
fn trans_simple_native_abi( @block_ctxt bcx,
6783
6795
str name,
6784
- vec[ ty. arg] args,
6785
6796
& mutable vec[ ValueRef ] call_args,
6786
- ty. t fn_type) -> tup( ValueRef , ValueRef ) {
6797
+ ty. t fn_type,
6798
+ uint first_arg_n) -> tup( ValueRef , ValueRef ) {
6787
6799
let vec[ TypeRef ] call_arg_tys = vec( ) ;
6788
- auto i = 0 u;
6789
- while ( i < _vec. len[ ty. arg ] ( args ) ) {
6790
- auto call_arg = llvm. LLVMGetParam ( bcx. fcx . llfn , i + 3 u) ;
6791
- call_args += vec ( call_arg) ;
6792
- call_arg_tys += vec ( val_ty ( call_arg) ) ;
6793
- i += 1 u;
6800
+ for ( ValueRef arg in call_args) {
6801
+ call_arg_tys += vec( val_ty( arg) ) ;
6794
6802
}
6803
+
6795
6804
auto llnativefnty =
6796
6805
T_fn ( call_arg_tys,
6797
6806
type_of( bcx. fcx. lcx. ccx,
6798
6807
ty. ty_fn_ret( bcx. fcx. lcx. ccx. tcx, fn_type) ) ) ;
6808
+
6799
6809
auto llnativefn = get_extern_fn( bcx. fcx. lcx. ccx. externs,
6800
6810
bcx. fcx. lcx. ccx. llmod,
6801
6811
name,
6802
6812
lib. llvm. LLVMCCallConv ,
6803
6813
llnativefnty) ;
6804
6814
6815
+ log_err "calling: " + val_str( bcx. fcx. lcx. ccx. tn, llnativefn) ;
6816
+
6817
+ for ( ValueRef arg in call_args) {
6818
+ log_err "arg: " + val_str( bcx. fcx. lcx. ccx. tn, arg) ;
6819
+ }
6820
+
6805
6821
auto r = bcx. build. Call ( llnativefn, call_args) ;
6806
6822
auto rptr = bcx. fcx. llretptr;
6807
6823
ret tup( r, rptr) ;
6808
6824
}
6809
6825
6826
+ auto args = ty. ty_fn_args( ccx. tcx, fn_type) ;
6827
+
6828
+ // Build up the list of arguments.
6829
+ let vec[ tup( ValueRef , ty. t) ] drop_args = vec( ) ;
6830
+ auto i = arg_n;
6831
+ for ( ty. arg arg in args) {
6832
+ auto llarg = llvm. LLVMGetParam ( fcx. llfn, i) ;
6833
+ assert ( llarg as int != 0 ) ;
6834
+
6835
+ if ( cast_to_i32) {
6836
+ auto llarg_i32 = convert_arg_to_i32( bcx, llarg, arg. ty, arg. mode) ;
6837
+ call_args += vec( llarg_i32) ;
6838
+ } else {
6839
+ call_args += vec( llarg) ;
6840
+ }
6841
+
6842
+ if ( arg. mode == ast. val) {
6843
+ drop_args += vec( tup( llarg, arg. ty) ) ;
6844
+ }
6845
+
6846
+ i += 1 u;
6847
+ }
6848
+
6810
6849
auto r;
6811
6850
auto rptr;
6812
- auto args = ty. ty_fn_args ( ccx. tcx , fn_type) ;
6813
6851
alt ( abi) {
6814
6852
case ( ast. native_abi_llvm) {
6815
- auto result = trans_simple_native_abi ( bcx, name, args , call_args,
6816
- fn_type) ;
6853
+ auto result = trans_simple_native_abi( bcx, name, call_args,
6854
+ fn_type, arg_n ) ;
6817
6855
r = result. _0; rptr = result. _1;
6818
6856
}
6819
6857
case ( ast. native_abi_rust_intrinsic) {
6820
- auto result = trans_simple_native_abi ( bcx, name, args, call_args,
6821
- fn_type) ;
6858
+ auto external_name = "rust_intrinsic_" + name;
6859
+ auto result = trans_simple_native_abi( bcx, external_name,
6860
+ call_args, fn_type, arg_n) ;
6822
6861
r = result. _0; rptr = result. _1;
6823
6862
}
6824
6863
case ( _) {
6825
- let vec[ tup ( ValueRef , ty. t ) ] drop_args = vec ( ) ;
6826
-
6827
- for ( ty. arg arg in args) {
6828
- auto llarg = llvm. LLVMGetParam ( fcx. llfn, arg_n) ;
6829
- assert ( llarg as int != 0 ) ;
6830
- push_arg( bcx, call_args, llarg, arg. ty, arg. mode) ;
6831
- if ( arg. mode == ast. val) {
6832
- drop_args += vec( tup( llarg, arg. ty) ) ;
6833
- }
6834
- arg_n += 1 u;
6835
- }
6836
-
6837
6864
r = trans_native_call( bcx. build, ccx. glues, lltaskptr,
6838
6865
ccx. externs, ccx. tn, ccx. llmod, name,
6839
6866
pass_task, call_args) ;
6840
6867
rptr = bcx. build. BitCast ( fcx. llretptr, T_ptr ( T_i32 ( ) ) ) ;
6841
6868
6842
- for ( tup( ValueRef , ty. t) d in drop_args) {
6843
- bcx = drop_ty( bcx, d. _0, d. _1) . bcx;
6844
- }
6845
6869
}
6846
6870
}
6847
6871
@@ -6850,6 +6874,10 @@ fn decl_native_fn_and_pair(@crate_ctxt ccx,
6850
6874
// the FIXME above.
6851
6875
if ( !rty_is_nil) { bcx. build. Store ( r, rptr) ; }
6852
6876
6877
+ for ( tup( ValueRef , ty. t) d in drop_args) {
6878
+ bcx = drop_ty( bcx, d. _0, d. _1) . bcx;
6879
+ }
6880
+
6853
6881
bcx. build. RetVoid ( ) ;
6854
6882
6855
6883
// Tie up the llallocas -> lltop edge.
0 commit comments