@@ -4458,180 +4458,6 @@ fn trans_const(cx: @crate_ctxt, e: @ast::expr, id: ast::node_id) {
4458
4458
}
4459
4459
}
4460
4460
4461
- type c_stack_tys = {
4462
- arg_tys: [ TypeRef ] ,
4463
- ret_ty: TypeRef ,
4464
- ret_def: bool,
4465
- base_fn_ty: TypeRef ,
4466
- bundle_ty: TypeRef ,
4467
- shim_fn_ty: TypeRef
4468
- } ;
4469
-
4470
- fn c_stack_tys ( ccx : @crate_ctxt ,
4471
- id : ast:: node_id ) -> @c_stack_tys {
4472
- alt ty:: get ( ty:: node_id_to_type ( ccx. tcx , id) ) . struct {
4473
- ty:: ty_fn ( { inputs: arg_tys, output: ret_ty, _} ) {
4474
- let llargtys = type_of_explicit_args ( ccx, arg_tys) ;
4475
- let llretty = type_of ( ccx, ret_ty) ;
4476
- let bundle_ty = T_struct ( llargtys + [ T_ptr ( llretty) ] ) ;
4477
- ret @{
4478
- arg_tys : llargtys,
4479
- ret_ty : llretty,
4480
- ret_def : !ty:: type_is_bot ( ret_ty) && !ty:: type_is_nil ( ret_ty) ,
4481
- base_fn_ty : T_fn ( llargtys, llretty) ,
4482
- bundle_ty : bundle_ty,
4483
- shim_fn_ty : T_fn ( [ T_ptr ( bundle_ty) ] , T_void ( ) )
4484
- } ;
4485
- }
4486
- _ {
4487
- // Precondition?
4488
- ccx. tcx . sess . bug ( "c_stack_tys called on non-function type" ) ;
4489
- }
4490
- }
4491
- }
4492
-
4493
- // For each native function F, we generate a wrapper function W and a shim
4494
- // function S that all work together. The wrapper function W is the function
4495
- // that other rust code actually invokes. Its job is to marshall the
4496
- // arguments into a struct. It then uses a small bit of assembly to switch
4497
- // over to the C stack and invoke the shim function. The shim function S then
4498
- // unpacks the arguments from the struct and invokes the actual function F
4499
- // according to its specified calling convention.
4500
- //
4501
- // Example: Given a native c-stack function F(x: X, y: Y) -> Z,
4502
- // we generate a wrapper function W that looks like:
4503
- //
4504
- // void W(Z* dest, void *env, X x, Y y) {
4505
- // struct { X x; Y y; Z *z; } args = { x, y, z };
4506
- // call_on_c_stack_shim(S, &args);
4507
- // }
4508
- //
4509
- // The shim function S then looks something like:
4510
- //
4511
- // void S(struct { X x; Y y; Z *z; } *args) {
4512
- // *args->z = F(args->x, args->y);
4513
- // }
4514
- //
4515
- // However, if the return type of F is dynamically sized or of aggregate type,
4516
- // the shim function looks like:
4517
- //
4518
- // void S(struct { X x; Y y; Z *z; } *args) {
4519
- // F(args->z, args->x, args->y);
4520
- // }
4521
- //
4522
- // Note: on i386, the layout of the args struct is generally the same as the
4523
- // desired layout of the arguments on the C stack. Therefore, we could use
4524
- // upcall_alloc_c_stack() to allocate the `args` structure and switch the
4525
- // stack pointer appropriately to avoid a round of copies. (In fact, the shim
4526
- // function itself is unnecessary). We used to do this, in fact, and will
4527
- // perhaps do so in the future.
4528
- fn trans_native_mod ( ccx : @crate_ctxt ,
4529
- native_mod : ast:: native_mod , abi : ast:: native_abi ) {
4530
- fn build_shim_fn ( ccx : @crate_ctxt ,
4531
- native_item : @ast:: native_item ,
4532
- tys : @c_stack_tys ,
4533
- cc : lib:: llvm:: CallConv ) -> ValueRef {
4534
- let lname = link_name ( native_item) ;
4535
-
4536
- // Declare the "prototype" for the base function F:
4537
- let llbasefn = decl_fn ( ccx. llmod , lname, cc, tys. base_fn_ty ) ;
4538
-
4539
- // Create the shim function:
4540
- let shim_name = lname + "__c_stack_shim" ;
4541
- let llshimfn = decl_internal_cdecl_fn (
4542
- ccx. llmod , shim_name, tys. shim_fn_ty ) ;
4543
-
4544
- // Declare the body of the shim function:
4545
- let fcx = new_fn_ctxt ( ccx, [ ] , llshimfn, none) ;
4546
- let bcx = new_top_block_ctxt ( fcx, none) ;
4547
- let lltop = bcx. llbb ;
4548
- let llargbundle = llvm:: LLVMGetParam ( llshimfn, 0 as c_uint ) ;
4549
- let i = 0 u, n = tys. arg_tys . len ( ) ;
4550
- let llargvals = [ ] ;
4551
- while i < n {
4552
- let llargval = load_inbounds ( bcx, llargbundle, [ 0 , i as int ] ) ;
4553
- llargvals += [ llargval] ;
4554
- i += 1 u;
4555
- }
4556
-
4557
- // Create the call itself and store the return value:
4558
- let llretval = CallWithConv ( bcx, llbasefn,
4559
- llargvals, cc) ; // r
4560
- if tys. ret_def {
4561
- // R** llretptr = &args->r;
4562
- let llretptr = GEPi ( bcx, llargbundle, [ 0 , n as int ] ) ;
4563
- // R* llretloc = *llretptr; /* (args->r) */
4564
- let llretloc = Load ( bcx, llretptr) ;
4565
- // *args->r = r;
4566
- Store ( bcx, llretval, llretloc) ;
4567
- }
4568
-
4569
- // Finish up:
4570
- build_return ( bcx) ;
4571
- finish_fn ( fcx, lltop) ;
4572
-
4573
- ret llshimfn;
4574
- }
4575
-
4576
- fn build_wrap_fn ( ccx : @crate_ctxt ,
4577
- tys : @c_stack_tys ,
4578
- num_tps : uint ,
4579
- llshimfn : ValueRef ,
4580
- llwrapfn : ValueRef ) {
4581
- let fcx = new_fn_ctxt ( ccx, [ ] , llwrapfn, none) ;
4582
- let bcx = new_top_block_ctxt ( fcx, none) ;
4583
- let lltop = bcx. llbb ;
4584
-
4585
- // Allocate the struct and write the arguments into it.
4586
- let llargbundle = alloca ( bcx, tys. bundle_ty ) ;
4587
- let i = 0 u, n = tys. arg_tys . len ( ) ;
4588
- let implicit_args = 2 u + num_tps; // ret + env
4589
- while i < n {
4590
- let llargval = llvm:: LLVMGetParam ( llwrapfn,
4591
- ( i + implicit_args) as c_uint ) ;
4592
- store_inbounds ( bcx, llargval, llargbundle, [ 0 , i as int ] ) ;
4593
- i += 1 u;
4594
- }
4595
- let llretptr = llvm:: LLVMGetParam ( llwrapfn, 0 as c_uint ) ;
4596
- store_inbounds ( bcx, llretptr, llargbundle, [ 0 , n as int ] ) ;
4597
-
4598
- // Create call itself.
4599
- let call_shim_on_c_stack = ccx. upcalls . call_shim_on_c_stack ;
4600
- let llshimfnptr = PointerCast ( bcx, llshimfn, T_ptr ( T_i8 ( ) ) ) ;
4601
- let llrawargbundle = PointerCast ( bcx, llargbundle, T_ptr ( T_i8 ( ) ) ) ;
4602
- Call ( bcx, call_shim_on_c_stack, [ llrawargbundle, llshimfnptr] ) ;
4603
- build_return ( bcx) ;
4604
- finish_fn ( fcx, lltop) ;
4605
- }
4606
-
4607
- let cc = lib:: llvm:: CCallConv ;
4608
- alt abi {
4609
- ast : : native_abi_rust_intrinsic { ret; }
4610
- ast:: native_abi_cdecl { cc = lib:: llvm:: CCallConv ; }
4611
- ast:: native_abi_stdcall { cc = lib:: llvm:: X86StdcallCallConv ; }
4612
- }
4613
-
4614
- for native_item in native_mod. items {
4615
- alt native_item. node {
4616
- ast:: native_item_fn ( fn_decl, tps) {
4617
- let id = native_item. id ;
4618
- let tys = c_stack_tys ( ccx, id) ;
4619
- alt ccx. item_ids . find ( id) {
4620
- some ( llwrapfn) {
4621
- let llshimfn = build_shim_fn ( ccx, native_item, tys, cc) ;
4622
- build_wrap_fn ( ccx, tys, tps. len ( ) , llshimfn, llwrapfn) ;
4623
- }
4624
- none {
4625
- ccx. sess . span_fatal (
4626
- native_item. span ,
4627
- "unbound function item in trans_native_mod" ) ;
4628
- }
4629
- }
4630
- }
4631
- }
4632
- }
4633
- }
4634
-
4635
4461
fn trans_item ( ccx : @crate_ctxt , item : ast:: item ) {
4636
4462
let path = alt ccx. tcx . items . get ( item. id ) {
4637
4463
ast_map:: node_item ( _, p) { p }
@@ -4690,7 +4516,7 @@ fn trans_item(ccx: @crate_ctxt, item: ast::item) {
4690
4516
either:: right ( abi_) { abi_ }
4691
4517
either:: left ( msg) { ccx. sess . span_fatal ( item. span , msg) }
4692
4518
} ;
4693
- trans_native_mod ( ccx, native_mod, abi) ;
4519
+ native :: trans_native_mod ( ccx, native_mod, abi) ;
4694
4520
}
4695
4521
_ { /* fall through */ }
4696
4522
}
@@ -4837,13 +4663,6 @@ fn fill_fn_pair(bcx: @block_ctxt, pair: ValueRef, llfn: ValueRef,
4837
4663
Store ( bcx, llenvblobptr, env_cell) ;
4838
4664
}
4839
4665
4840
- fn link_name ( i : @ast:: native_item ) -> str {
4841
- alt attr:: get_meta_item_value_str_by_name ( i. attrs , "link_name" ) {
4842
- none { ret i. ident ; }
4843
- option:: some ( ln) { ret ln; }
4844
- }
4845
- }
4846
-
4847
4666
fn collect_native_item ( ccx : @crate_ctxt ,
4848
4667
abi : @mutable option < ast:: native_abi > ,
4849
4668
i : @ast:: native_item ) {
@@ -4872,7 +4691,7 @@ fn collect_native_item(ccx: @crate_ctxt,
4872
4691
let fn_type = type_of_fn_from_ty (
4873
4692
ccx, node_type,
4874
4693
vec:: map ( tps, { |p| param_bounds ( ccx, p) } ) ) ;
4875
- let ri_name = "rust_intrinsic_" + link_name ( i) ;
4694
+ let ri_name = "rust_intrinsic_" + native :: link_name ( i) ;
4876
4695
let llnativefn = get_extern_fn (
4877
4696
ccx. externs , ccx. llmod , ri_name,
4878
4697
lib:: llvm:: CCallConv , fn_type) ;
0 commit comments