@@ -183,12 +183,8 @@ fn type_of_inner(cx: @crate_ctxt, sp: span, t: ty::t)
183
183
T_fn_pair ( cx, type_of_fn_from_ty ( cx, sp, t, 0 u) )
184
184
}
185
185
ty:: ty_native_fn ( abi, args, out) {
186
- if native_abi_requires_pair ( abi) {
187
- let nft = native_fn_wrapper_type ( cx, sp, 0 u, t) ;
188
- T_fn_pair ( cx, nft)
189
- } else {
190
- raw_native_fn_type ( cx, sp, args, out)
191
- }
186
+ let nft = native_fn_wrapper_type ( cx, sp, 0 u, t) ;
187
+ T_fn_pair ( cx, nft)
192
188
}
193
189
ty:: ty_obj ( meths) { cx. rust_object_type }
194
190
ty:: ty_res ( _, sub, tps) {
@@ -3766,9 +3762,9 @@ fn trans_call(in_cx: @block_ctxt, f: @ast::expr,
3766
3762
let tcx = bcx_tcx ( in_cx) ;
3767
3763
let fn_expr_ty = ty:: expr_ty ( tcx, f) ;
3768
3764
3769
- if check type_is_native_fn_on_c_stack ( tcx, fn_expr_ty) {
3770
- ret trans_c_stack_native_call ( in_cx, f, args, dest) ;
3771
- }
3765
+ //NDM if check type_is_native_fn_on_c_stack(tcx, fn_expr_ty) {
3766
+ //NDM ret trans_c_stack_native_call(in_cx, f, args, dest);
3767
+ //NDM }
3772
3768
3773
3769
let cx = new_scope_block_ctxt ( in_cx, "call" ) ;
3774
3770
let f_res = trans_callee ( cx, f) ;
@@ -3832,63 +3828,6 @@ fn trans_call(in_cx: @block_ctxt, f: @ast::expr,
3832
3828
ret next_cx;
3833
3829
}
3834
3830
3835
- // Translates a native call on the C stack. Calls into the runtime to perform
3836
- // the stack switching operation. Must be kept in sync with
3837
- // trans_native_mod().
3838
- fn trans_c_stack_native_call ( bcx : @block_ctxt , f : @ast:: expr ,
3839
- args : [ @ast:: expr ] , dest : dest ) -> @block_ctxt {
3840
- let ccx = bcx_ccx ( bcx) ;
3841
- let f_res = trans_callee ( bcx, f) ;
3842
- let llfn = f_res. val , bcx = f_res. bcx ;
3843
- let llfn = BitCast ( bcx, llfn, T_ptr ( T_fn ( [ ] , bcx_ccx ( bcx) . int_type ) ) ) ;
3844
-
3845
- // Translate the callee.
3846
- let { params: _ , ty: fn_ty } = ty:: expr_ty_params_and_ty ( bcx_tcx ( bcx) , f) ;
3847
- let fn_arg_tys = ty:: ty_fn_args ( bcx_tcx ( bcx) , fn_ty) ;
3848
- let llargtys = type_of_explicit_args ( ccx, f. span , fn_arg_tys) ;
3849
-
3850
- // Determine return type.
3851
- let ret_ty = ty:: ty_fn_ret ( bcx_tcx ( bcx) , fn_ty) ;
3852
- check type_has_static_size ( ccx, ret_ty) ;
3853
- let llretty = type_of ( ccx, f. span , ret_ty) ;
3854
-
3855
- // Translate arguments.
3856
- // n.b.: We must do this before allocating the argument
3857
- // bundle in order to avoid problems with nested function calls.
3858
- let ( to_zero, to_revoke) = ( [ ] , [ ] ) ;
3859
- let i = 0 u, n = vec:: len ( args) ;
3860
- let llargs = [ ] ;
3861
- while i < n {
3862
- let ty_arg = fn_arg_tys[ i] ;
3863
- let arg = args[ i] ;
3864
- let llargty = llargtys[ i] ;
3865
- let r = trans_arg_expr ( bcx, ty_arg, llargty, to_zero, to_revoke, arg) ;
3866
- bcx = r. bcx ;
3867
- llargs += [ r. val ] ;
3868
- i += 1 u;
3869
- }
3870
-
3871
- // Allocate the argument bundle and store arguments.
3872
- let llargbundlety = T_struct ( llargtys + [ llretty] ) ;
3873
- let llargbundlesz = llsize_of ( ccx, llargbundlety) ;
3874
- let llrawargbundle = Call ( bcx, ccx. upcalls . alloc_c_stack ,
3875
- [ llargbundlesz] ) ;
3876
- let llargbundle = PointerCast ( bcx, llrawargbundle, T_ptr ( llargbundlety) ) ;
3877
- i = 0 u;
3878
- while i < n {
3879
- store_inbounds ( bcx, llargs[ i] , llargbundle, [ 0 , i as int ] ) ;
3880
- i += 1 u;
3881
- }
3882
-
3883
- // Call the upcall function then extract return value from the bundle.
3884
- let upcall_fn = ccx. upcalls . call_c_stack_shim ;
3885
- let llfnptr = PointerCast ( bcx, llfn, T_ptr ( T_i8 ( ) ) ) ;
3886
- Call ( bcx, upcall_fn, [ llfnptr, llrawargbundle] ) ;
3887
- let llres = load_inbounds ( bcx, llargbundle, [ 0 , n as int ] ) ;
3888
- bcx = zero_and_revoke ( bcx, to_zero, to_revoke) ;
3889
- ret store_in_dest ( bcx, llres, dest) ;
3890
- }
3891
-
3892
3831
fn zero_and_revoke ( bcx : @block_ctxt ,
3893
3832
to_zero : [ { v : ValueRef , t : ty:: t } ] ,
3894
3833
to_revoke : [ { v : ValueRef , t : ty:: t } ] ) -> @block_ctxt {
@@ -5354,6 +5293,7 @@ fn trans_const(cx: @crate_ctxt, e: @ast::expr, id: ast::node_id) {
5354
5293
type c_stack_tys = {
5355
5294
arg_tys : [ TypeRef ] ,
5356
5295
ret_ty : TypeRef ,
5296
+ ret_def : bool ,
5357
5297
base_fn_ty : TypeRef ,
5358
5298
bundle_ty : TypeRef ,
5359
5299
shim_fn_ty : TypeRef
@@ -5364,13 +5304,16 @@ fn c_stack_tys(ccx: @crate_ctxt,
5364
5304
id : ast:: node_id ) -> @c_stack_tys {
5365
5305
alt ty:: struct ( ccx. tcx , ty:: node_id_to_type ( ccx. tcx , id) ) {
5366
5306
ty:: ty_native_fn ( _, arg_tys, ret_ty) {
5307
+ let tcx = ccx. tcx ;
5367
5308
let llargtys = type_of_explicit_args ( ccx, sp, arg_tys) ;
5368
5309
check non_ty_var( ccx, ret_ty) ; // NDM does this truly hold?
5369
- let llretty = T_ptr ( type_of_inner ( ccx, sp, ret_ty) ) ;
5370
- let bundle_ty = T_struct ( llargtys + [ llretty] ) ;
5310
+ let llretty = type_of_inner ( ccx, sp, ret_ty) ;
5311
+ let bundle_ty = T_struct ( llargtys + [ T_ptr ( llretty) ] ) ;
5371
5312
ret @{
5372
5313
arg_tys : llargtys,
5373
5314
ret_ty : llretty,
5315
+ ret_def : !ty:: type_is_bot ( tcx, ret_ty) &&
5316
+ !ty:: type_is_nil ( tcx, ret_ty) ,
5374
5317
base_fn_ty : T_fn ( llargtys, llretty) ,
5375
5318
bundle_ty : bundle_ty,
5376
5319
shim_fn_ty : T_fn ( [ T_ptr ( bundle_ty) ] , T_void ( ) )
@@ -5451,8 +5394,15 @@ fn trans_native_mod(lcx: @local_ctxt, native_mod: ast::native_mod) {
5451
5394
}
5452
5395
5453
5396
// Create the call itself and store the return value:
5454
- let llretval = CallWithConv ( bcx, llbasefn, llargvals, cc) ;
5455
- store_inbounds ( bcx, llretval, llargbundle, [ 0 , n as int , 0 ] ) ;
5397
+ let llretval = CallWithConv ( bcx, llbasefn, llargvals, cc) ; // r
5398
+ if tys. ret_def {
5399
+ // R** llretptr = &args->r;
5400
+ let llretptr = GEPi ( bcx, llargbundle, [ 0 , n as int ] ) ;
5401
+ // R* llretloc = *llretptr; /* (args->r) */
5402
+ let llretloc = Load ( bcx, llretptr) ;
5403
+ // *args->r = r;
5404
+ Store ( bcx, llretval, llretloc) ;
5405
+ }
5456
5406
5457
5407
// Finish up:
5458
5408
build_return ( bcx) ;
@@ -5464,25 +5414,32 @@ fn trans_native_mod(lcx: @local_ctxt, native_mod: ast::native_mod) {
5464
5414
fn build_wrap_fn ( lcx : @local_ctxt ,
5465
5415
native_item : @ast:: native_item ,
5466
5416
tys : @c_stack_tys ,
5417
+ num_tps : uint ,
5467
5418
llshimfn : ValueRef ,
5468
5419
llwrapfn : ValueRef ) {
5469
- let fcx = new_fn_ctxt ( lcx, span, llshimfn) ;
5420
+ let span = native_item. span ;
5421
+ let ccx = lcx_ccx ( lcx) ;
5422
+ let fcx = new_fn_ctxt ( lcx, span, llwrapfn) ;
5470
5423
let bcx = new_top_block_ctxt ( fcx) ;
5471
5424
let lltop = bcx. llbb ;
5472
5425
5473
5426
// Allocate the struct and write the arguments into it.
5474
5427
let llargbundle = alloca ( bcx, tys. bundle_ty ) ;
5475
- let imp = 2 u, i = 0 u, n = vec:: len ( tys. arg_tys ) ;
5428
+ let i = 0 u, n = vec:: len ( tys. arg_tys ) ;
5429
+ let implicit_args = 2 u + num_tps; // ret + env
5476
5430
while i < n {
5477
- let llargval = llvm:: LLVMGetParam ( llwrapfn, i + imp ) ;
5431
+ let llargval = llvm:: LLVMGetParam ( llwrapfn, i + implicit_args ) ;
5478
5432
store_inbounds ( bcx, llargval, llargbundle, [ 0 , i as int ] ) ;
5479
5433
i += 1 u;
5480
5434
}
5481
- let llretptr = llvm:: LLVMGetParam ( llwrapfn, 0 ) ;
5435
+ let llretptr = llvm:: LLVMGetParam ( llwrapfn, 0 u ) ;
5482
5436
store_inbounds ( bcx, llretptr, llargbundle, [ 0 , n as int ] ) ;
5483
5437
5484
- // Create call itself:
5485
-
5438
+ // Create call itself.
5439
+ let call_shim_on_c_stack = ccx. upcalls . call_shim_on_c_stack ;
5440
+ let llshimfnptr = PointerCast ( bcx, llshimfn, T_ptr ( T_i8 ( ) ) ) ;
5441
+ let llrawargbundle = PointerCast ( bcx, llargbundle, T_ptr ( T_i8 ( ) ) ) ;
5442
+ Call ( bcx, call_shim_on_c_stack, [ llrawargbundle, llshimfnptr] ) ;
5486
5443
build_return ( bcx) ;
5487
5444
finish_fn ( fcx, lltop) ;
5488
5445
}
@@ -5498,13 +5455,15 @@ fn trans_native_mod(lcx: @local_ctxt, native_mod: ast::native_mod) {
5498
5455
for native_item in native_mod. items {
5499
5456
alt native_item. node {
5500
5457
ast:: native_item_ty. { }
5501
- ast:: native_item_fn ( fn_decl, _) {
5458
+ ast:: native_item_fn ( fn_decl, tps) {
5459
+ let span = native_item. span ;
5502
5460
let id = native_item. id ;
5503
5461
let tys = c_stack_tys ( ccx, span, id) ;
5504
5462
alt ccx. item_ids . find ( id) {
5505
5463
some ( llwrapfn) {
5506
- let llshimfn = build_shim_fn ( lcx, native_item, cc, tys) ;
5507
- build_wrap_fn ( lcx, native_item, tys, llshimfn, llwrapfn) ;
5464
+ let llshimfn = build_shim_fn ( lcx, native_item, tys, cc) ;
5465
+ build_wrap_fn ( lcx, native_item, tys,
5466
+ vec:: len ( tps) , llshimfn, llwrapfn) ;
5508
5467
}
5509
5468
5510
5469
none. {
@@ -5733,21 +5692,6 @@ fn native_fn_ty_param_count(cx: @crate_ctxt, id: ast::node_id) -> uint {
5733
5692
ret count;
5734
5693
}
5735
5694
5736
- pure fn native_abi_requires_pair ( abi: ast:: native_abi) -> bool {
5737
- alt abi {
5738
- ast : : native_abi_rust_intrinsic. { ret true ; }
5739
- ast:: native_abi_cdecl. |
5740
- ast:: native_abi_stdcall . { ret false; }
5741
- }
5742
- }
5743
-
5744
- pure fn type_is_native_fn_on_c_stack ( tcx : ty:: ctxt , t : ty:: t ) -> bool {
5745
- alt ty:: struct ( tcx, t) {
5746
- ty:: ty_native_fn ( abi, _, _) { ret ! native_abi_requires_pair( abi) ; }
5747
- _ { ret false; }
5748
- }
5749
- }
5750
-
5751
5695
fn native_fn_wrapper_type ( cx : @crate_ctxt , sp : span , ty_param_count : uint ,
5752
5696
x : ty:: t ) -> TypeRef {
5753
5697
alt ty:: struct ( cx. tcx , x) {
@@ -5778,19 +5722,24 @@ fn collect_native_item(ccx: @crate_ctxt, i: @ast::native_item, &&pt: [str],
5778
5722
alt i. node {
5779
5723
ast:: native_item_fn ( _, tps) {
5780
5724
if !ccx. obj_methods . contains_key ( i. id ) {
5725
+ let sp = i. span ;
5726
+ let id = i. id ;
5727
+ let node_type = node_id_type ( ccx, id) ;
5781
5728
// FIXME NDM abi should come from attr
5782
- let abi = ty:: ty_fn_abi ( ccx. tcx , fn_type ) ;
5729
+ let abi = ty:: ty_fn_abi ( ccx. tcx , node_type ) ;
5783
5730
5784
5731
alt abi {
5785
5732
ast : : native_abi_rust_intrinsic. {
5786
5733
// For intrinsics: link the function directly to the intrinsic
5787
5734
// function itself.
5788
5735
let num_ty_param = vec:: len ( tps) ;
5789
- let node_type = node_id_type ( ccx, id) ;
5790
- let fn_type = type_of_fn_from_ty ( ccx, sp, node_type, num_ty_param) ;
5791
- let ri_name = "rust_intrinsic_" + name;
5792
- let llnativefn = get_extern_fn ( ccx. externs , ccx. llmod , ri_name,
5793
- lib:: llvm:: LLVMCCallConv , fn_type) ;
5736
+ check returns_non_ty_var ( ccx, node_type) ;
5737
+ let fn_type = type_of_fn_from_ty ( ccx, sp, node_type,
5738
+ num_ty_param) ;
5739
+ let ri_name = "rust_intrinsic_" + link_name ( i) ;
5740
+ let llnativefn = get_extern_fn (
5741
+ ccx. externs , ccx. llmod , ri_name,
5742
+ lib:: llvm:: LLVMCCallConv , fn_type) ;
5794
5743
ccx. item_ids . insert ( id, llnativefn) ;
5795
5744
ccx. item_symbols . insert ( id, ri_name) ;
5796
5745
}
0 commit comments