@@ -53,7 +53,8 @@ state obj namegen(mutable int i) {
53
53
type glue_fns = rec ( ValueRef activate_glue ,
54
54
ValueRef yield_glue ,
55
55
ValueRef exit_task_glue ,
56
- vec[ ValueRef ] upcall_glues ,
56
+ vec[ ValueRef ] upcall_glues_rust ,
57
+ vec[ ValueRef ] upcall_glues_cdecl ,
57
58
ValueRef no_op_type_glue ,
58
59
ValueRef memcpy_glue ,
59
60
ValueRef bzero_glue ,
@@ -71,7 +72,6 @@ state type crate_ctxt = rec(session.session sess,
71
72
hashmap[ str, ValueRef ] upcalls,
72
73
hashmap[ str, ValueRef ] intrinsics,
73
74
hashmap[ str, ValueRef ] item_names,
74
- hashmap[ str, ValueRef ] native_fns,
75
75
hashmap[ ast. def_id , ValueRef ] item_ids,
76
76
hashmap[ ast. def_id , @ast. item ] items,
77
77
hashmap[ ast. def_id ,
@@ -826,16 +826,19 @@ fn decl_glue(ModuleRef llmod, type_names tn, str s) -> ValueRef {
826
826
ret decl_cdecl_fn ( llmod, s, T_fn ( vec ( T_taskptr ( tn) ) , T_void ( ) ) ) ;
827
827
}
828
828
829
- fn decl_upcall_glue ( ModuleRef llmod, type_names tn, uint _n) -> ValueRef {
829
+ fn decl_upcall_glue ( ModuleRef llmod, type_names tn,
830
+ bool pass_task , uint _n) -> ValueRef {
830
831
// It doesn't actually matter what type we come up with here, at the
831
832
// moment, as we cast the upcall function pointers to int before passing
832
833
// them to the indirect upcall-invocation glue. But eventually we'd like
833
834
// to call them directly, once we have a calling convention worked out.
834
835
let int n = _n as int ;
835
- let str s = abi. upcall_glue_name ( n) ;
836
- let vec[ TypeRef ] args =
837
- vec ( T_int ( ) ) // callee
838
- + _vec. init_elt [ TypeRef ] ( T_int ( ) , n as uint ) ;
836
+ let str s = abi. upcall_glue_name ( n, pass_task) ;
837
+ let vec[ TypeRef ] args = vec ( T_int ( ) ) ; // callee
838
+ if ( !pass_task) {
839
+ args += vec ( T_int ( ) ) ; // taskptr, will not be passed
840
+ }
841
+ args += _vec. init_elt [ TypeRef ] ( T_int ( ) , n as uint ) ;
839
842
840
843
ret decl_fastcall_fn ( llmod, s, T_fn ( args, T_int ( ) ) ) ;
841
844
}
@@ -856,21 +859,29 @@ fn trans_upcall(@block_ctxt cx, str name, vec[ValueRef] args) -> result {
856
859
auto cxx = cx. fcx . ccx ;
857
860
auto lltaskptr = cx. build . PtrToInt ( cx. fcx . lltaskptr , T_int ( ) ) ;
858
861
auto args2 = vec ( lltaskptr) + args;
859
- auto t = trans_upcall2 ( cx. build , cxx. glues ,
860
- cxx. upcalls , cxx. tn , cxx. llmod , name, args2) ;
862
+ auto t = trans_upcall2 ( cx. build , cxx. glues , lltaskptr ,
863
+ cxx. upcalls , cxx. tn , cxx. llmod , name, true , args2) ;
861
864
ret res( cx, t) ;
862
865
}
863
866
864
- fn trans_upcall2 ( builder b, @glue_fns glues ,
867
+ fn trans_upcall2 ( builder b, @glue_fns glues , ValueRef lltaskptr ,
865
868
& hashmap[ str, ValueRef ] upcalls ,
866
869
type_names tn, ModuleRef llmod, str name ,
867
- vec[ ValueRef ] args ) -> ValueRef {
870
+ bool pass_task , vec[ ValueRef ] args ) -> ValueRef {
868
871
let int n = ( _vec. len [ ValueRef ] ( args) as int ) ;
869
872
let ValueRef llupcall = get_upcall ( upcalls, llmod, name, n) ;
870
873
llupcall = llvm. LLVMConstPointerCast ( llupcall, T_int ( ) ) ;
871
874
872
- let ValueRef llglue = glues. upcall_glues . ( n) ;
875
+ let ValueRef llglue;
876
+ if ( pass_task) {
877
+ llglue = glues. upcall_glues_rust . ( n) ;
878
+ } else {
879
+ llglue = glues. upcall_glues_cdecl . ( n) ;
880
+ }
873
881
let vec[ ValueRef ] call_args = vec ( llupcall) ;
882
+ if ( !pass_task) {
883
+ call_args += vec ( lltaskptr) ;
884
+ }
874
885
875
886
for ( ValueRef a in args) {
876
887
call_args += vec ( b. ZExtOrBitCast ( a, T_int ( ) ) ) ;
@@ -5457,44 +5468,38 @@ fn decl_native_fn_and_pair(@crate_ctxt cx,
5457
5468
auto llfnty = type_of_native_fn ( cx, abi, ty. ty_fn_args ( fn_type) ,
5458
5469
ty. ty_fn_ret ( fn_type) , num_ty_param) ;
5459
5470
5460
- // We can only declare a native function with a given name once; LLVM
5461
- // unhelpfully mangles the names if we try to multiply declare one.
5462
- auto function;
5463
- if ( !cx. native_fns . contains_key ( name) ) {
5464
- function = decl_cdecl_fn ( cx. llmod , name, llfnty) ;
5465
- cx. native_fns . insert ( name, function) ;
5466
- } else {
5467
- // We support type-punning a native function by giving it different
5468
- // Rust types.
5469
- auto llorigfn = cx. native_fns . get ( name) ;
5470
- function = bcx. build . PointerCast ( llorigfn, T_ptr ( llfnty) ) ;
5471
- }
5472
-
5473
5471
let vec[ ValueRef ] call_args = vec ( ) ;
5474
5472
auto arg_n = 3 u;
5473
+ auto pass_task;
5474
+
5475
+ auto lltaskptr = bcx. build . PtrToInt ( fcx. lltaskptr , T_int ( ) ) ;
5475
5476
alt ( abi) {
5476
5477
case ( ast. native_abi_rust ) {
5477
- call_args += vec ( fcx. lltaskptr ) ;
5478
+ pass_task = true ;
5479
+ call_args += vec ( lltaskptr) ;
5478
5480
for each ( uint i in _uint. range( 0 u, num_ty_param) ) {
5479
5481
auto llarg = llvm. LLVMGetParam ( fcx. llfn, arg_n) ;
5480
5482
check ( llarg as int != 0 ) ;
5481
- call_args += vec( llarg) ;
5483
+ call_args += vec( bcx . build . PointerCast ( llarg, T_i32 ( ) ) ) ;
5482
5484
arg_n += 1 u;
5483
5485
}
5484
5486
}
5485
5487
case ( ast. native_abi_cdecl) {
5488
+ pass_task = false ;
5486
5489
}
5487
5490
}
5488
5491
auto args = ty. ty_fn_args( fn_type) ;
5489
5492
for ( ty. arg arg in args) {
5490
5493
auto llarg = llvm. LLVMGetParam ( fcx. llfn, arg_n) ;
5491
5494
check ( llarg as int != 0 ) ;
5492
- call_args += vec( llarg) ;
5495
+ call_args += vec( bcx . build . PointerCast ( llarg, T_i32 ( ) ) ) ;
5493
5496
arg_n += 1 u;
5494
5497
}
5495
5498
5496
- auto r = bcx. build. Call ( function, call_args) ;
5497
- bcx. build. Store ( r, fcx. llretptr) ;
5499
+ auto r = trans_upcall2( bcx. build, cx. glues, lltaskptr, cx. upcalls, cx. tn,
5500
+ cx. llmod, name, pass_task, call_args) ;
5501
+ auto rptr = bcx. build. BitCast ( fcx. llretptr, T_ptr ( T_i32 ( ) ) ) ;
5502
+ bcx. build. Store ( r, rptr) ;
5498
5503
bcx. build. RetVoid ( ) ;
5499
5504
}
5500
5505
@@ -5695,8 +5700,8 @@ fn trans_exit_task_glue(@glue_fns glues,
5695
5700
auto build = new_builder ( entrybb) ;
5696
5701
auto tptr = build. PtrToInt ( lltaskptr, T_int ( ) ) ;
5697
5702
auto V_args2 = vec ( tptr) + V_args ;
5698
- trans_upcall2 ( build, glues,
5699
- upcalls, tn, llmod, "upcall_exit" , V_args2 ) ;
5703
+ trans_upcall2 ( build, glues, lltaskptr ,
5704
+ upcalls, tn, llmod, "upcall_exit" , true , V_args2 ) ;
5700
5705
build. RetVoid ( ) ;
5701
5706
}
5702
5707
@@ -6146,8 +6151,13 @@ fn make_glues(ModuleRef llmod, type_names tn) -> @glue_fns {
6146
6151
T_taskptr ( tn) ) ,
6147
6152
T_void ( ) ) ) ,
6148
6153
6149
- upcall_glues =
6150
- _vec. init_fn [ ValueRef ] ( bind decl_upcall_glue ( llmod, tn, _) ,
6154
+ upcall_glues_rust =
6155
+ _vec. init_fn [ ValueRef ] ( bind decl_upcall_glue ( llmod, tn, true ,
6156
+ _) ,
6157
+ abi. n_upcall_glues + 1 as uint ) ,
6158
+ upcall_glues_cdecl =
6159
+ _vec. init_fn [ ValueRef ] ( bind decl_upcall_glue ( llmod, tn, false ,
6160
+ _) ,
6151
6161
abi. n_upcall_glues + 1 as uint ) ,
6152
6162
no_op_type_glue = decl_no_op_type_glue ( llmod, tn) ,
6153
6163
memcpy_glue = decl_memcpy_glue ( llmod) ,
@@ -6217,7 +6227,6 @@ fn trans_crate(session.session sess, @ast.crate crate, str output,
6217
6227
upcalls = new_str_hash[ ValueRef ] ( ) ,
6218
6228
intrinsics = intrinsics,
6219
6229
item_names = new_str_hash[ ValueRef ] ( ) ,
6220
- native_fns = new_str_hash[ ValueRef ] ( ) ,
6221
6230
item_ids = new_def_hash[ ValueRef ] ( ) ,
6222
6231
items = new_def_hash[ @ast. item ] ( ) ,
6223
6232
native_items = new_def_hash[ @ast. native_item ] ( ) ,
0 commit comments