Skip to content

Commit 41109d0

Browse files
committed
---
yaml --- r: 273242 b: refs/heads/beta c: 200d001 h: refs/heads/master
1 parent 8569dad commit 41109d0

File tree

3 files changed

+69
-43
lines changed

3 files changed

+69
-43
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ refs/tags/0.9: 36870b185fc5f5486636d4515f0e22677493f225
2323
refs/tags/0.10: ac33f2b15782272ae348dbd7b14b8257b2148b5a
2424
refs/tags/0.11.0: e1247cb1d0d681be034adb4b558b5a0c0d5720f9
2525
refs/tags/0.12.0: f0c419429ef30723ceaf6b42f9b5a2aeb5d2e2d1
26-
refs/heads/beta: 3342da41135a63ba6d20c3f3e90fb40419164706
26+
refs/heads/beta: 200d001784e62c85d0e938637ce4043162aa94fd
2727
refs/tags/1.0.0-alpha: e42bd6d93a1d3433c486200587f8f9e12590a4d7
2828
refs/heads/tmp: e06d2ad9fcd5027bcaac5b08fc9aa39a49d0ecd3
2929
refs/tags/1.0.0-alpha.2: 4c705f6bc559886632d3871b04f58aab093bfa2f

branches/beta/src/librustc_trans/trans/abi.rs

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ pub use self::ArgKind::*;
1212

1313
use llvm::{self, AttrHelper, ValueRef};
1414
use trans::attributes;
15-
use trans::common::return_type_is_void;
15+
use trans::common::{return_type_is_void, type_is_fat_ptr};
1616
use trans::context::CrateContext;
1717
use trans::cabi_x86;
1818
use trans::cabi_x86_64;
@@ -184,10 +184,20 @@ impl FnType {
184184
_ => Type::void(ccx)
185185
};
186186

187+
let mut args = Vec::with_capacity(sig.inputs.len() + extra_args.len());
188+
for ty in sig.inputs.iter().chain(extra_args.iter()) {
189+
let llty = c_type_of(ccx, ty);
190+
if type_is_fat_ptr(ccx.tcx(), ty) {
191+
args.extend(llty.field_types().into_iter().map(|llty| {
192+
ArgType::direct(llty, None, None, None)
193+
}));
194+
} else {
195+
args.push(ArgType::direct(llty, None, None, None));
196+
}
197+
}
198+
187199
let mut fty = FnType {
188-
args: sig.inputs.iter().chain(extra_args.iter()).map(|&ty| {
189-
ArgType::direct(c_type_of(ccx, ty), None, None, None)
190-
}).collect(),
200+
args: args,
191201
ret: ArgType::direct(rty, None, None, None),
192202
variadic: sig.variadic,
193203
cconv: cconv

branches/beta/src/librustc_trans/trans/foreign.rs

Lines changed: 54 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -13,19 +13,17 @@ use back::link;
1313
use llvm::{ValueRef, get_param};
1414
use llvm;
1515
use middle::weak_lang_items;
16-
use trans::abi::{self, Abi, FnType};
16+
use trans::abi::{Abi, FnType};
1717
use trans::attributes;
1818
use trans::base::{llvm_linkage_by_name, push_ctxt};
1919
use trans::base;
2020
use trans::build::*;
2121
use trans::common::*;
2222
use trans::debuginfo::DebugLoc;
2323
use trans::declare;
24-
use trans::expr;
2524
use trans::machine;
2625
use trans::monomorphize;
2726
use trans::type_::Type;
28-
use trans::type_of::*;
2927
use trans::type_of;
3028
use trans::value::Value;
3129
use middle::infer;
@@ -167,17 +165,40 @@ pub fn trans_native_call<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
167165
}
168166
}
169167

170-
let mut offset = 0;
171-
for (i, arg_ty) in fn_type.args.iter().enumerate() {
172-
let mut llarg_rust = llargs_rust[i + offset];
168+
let mut i = 0;
169+
for &passed_arg_ty in &passed_arg_tys {
170+
let arg_ty = fn_type.args[i];
173171

174172
if arg_ty.is_ignore() {
173+
i += 1;
174+
continue;
175+
}
176+
177+
if type_is_fat_ptr(ccx.tcx(), passed_arg_ty) {
178+
// Fat pointers are one pointer and one integer or pointer.
179+
let (a, b) = (fn_type.args[i], fn_type.args[i + 1]);
180+
assert_eq!((a.cast, b.cast), (None, None));
181+
assert!(!a.is_indirect() && !b.is_indirect());
182+
183+
if let Some(ty) = a.pad {
184+
llargs_foreign.push(C_undef(ty));
185+
}
186+
llargs_foreign.push(llargs_rust[i]);
187+
i += 1;
188+
189+
if let Some(ty) = b.pad {
190+
llargs_foreign.push(C_undef(ty));
191+
}
192+
llargs_foreign.push(llargs_rust[i]);
193+
i += 1;
175194
continue;
176195
}
177196

178197
// Does Rust pass this argument by pointer?
179-
let rust_indirect = type_of::arg_is_indirect(ccx, passed_arg_tys[i]);
198+
let rust_indirect = type_of::arg_is_indirect(ccx, passed_arg_ty);
180199

200+
let mut llarg_rust = llargs_rust[i];
201+
i += 1;
181202
debug!("argument {}, llarg_rust={:?}, rust_indirect={}, arg_ty={:?}",
182203
i,
183204
Value(llarg_rust),
@@ -187,24 +208,17 @@ pub fn trans_native_call<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
187208
// Ensure that we always have the Rust value indirectly,
188209
// because it makes bitcasting easier.
189210
if !rust_indirect {
190-
let scratch = base::alloc_ty(bcx, passed_arg_tys[i], "__arg");
191-
if type_is_fat_ptr(ccx.tcx(), passed_arg_tys[i]) {
192-
Store(bcx, llargs_rust[i + offset], expr::get_dataptr(bcx, scratch));
193-
Store(bcx, llargs_rust[i + offset + 1], expr::get_meta(bcx, scratch));
194-
offset += 1;
195-
} else {
196-
base::store_ty(bcx, llarg_rust, scratch, passed_arg_tys[i]);
197-
}
211+
let scratch = base::alloc_ty(bcx, passed_arg_ty, "__arg");
212+
base::store_ty(bcx, llarg_rust, scratch, passed_arg_ty);
198213
llarg_rust = scratch;
199214
}
200215

201216
debug!("llarg_rust={:?} (after indirection)",
202217
Value(llarg_rust));
203218

204219
// Check whether we need to do any casting
205-
match arg_ty.cast {
206-
Some(ty) => llarg_rust = BitCast(bcx, llarg_rust, ty.ptr_to()),
207-
None => ()
220+
if let Some(ty) = arg_ty.cast {
221+
llarg_rust = BitCast(bcx, llarg_rust, ty.ptr_to());
208222
}
209223

210224
debug!("llarg_rust={:?} (after casting)",
@@ -214,22 +228,19 @@ pub fn trans_native_call<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
214228
let foreign_indirect = arg_ty.is_indirect();
215229
let llarg_foreign = if foreign_indirect {
216230
llarg_rust
231+
} else if passed_arg_ty.is_bool() {
232+
let val = LoadRangeAssert(bcx, llarg_rust, 0, 2, llvm::False);
233+
Trunc(bcx, val, Type::i1(bcx.ccx()))
217234
} else {
218-
if passed_arg_tys[i].is_bool() {
219-
let val = LoadRangeAssert(bcx, llarg_rust, 0, 2, llvm::False);
220-
Trunc(bcx, val, Type::i1(bcx.ccx()))
221-
} else {
222-
Load(bcx, llarg_rust)
223-
}
235+
Load(bcx, llarg_rust)
224236
};
225237

226238
debug!("argument {}, llarg_foreign={:?}",
227239
i, Value(llarg_foreign));
228240

229241
// fill padding with undef value
230-
match arg_ty.pad {
231-
Some(ty) => llargs_foreign.push(C_undef(ty)),
232-
None => ()
242+
if let Some(ty) = arg_ty.pad {
243+
llargs_foreign.push(C_undef(ty));
233244
}
234245
llargs_foreign.push(llarg_foreign);
235246
}
@@ -552,16 +563,16 @@ pub fn trans_rust_fn_with_foreign_abi<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
552563
// Build up the arguments to the call to the rust function.
553564
// Careful to adapt for cases where the native convention uses
554565
// a pointer and Rust does not or vice versa.
566+
let mut tys = fn_ty.args.iter().zip(rust_param_tys);
555567
for i in 0..fn_sig.inputs.len() {
556568
let rust_ty = fn_sig.inputs[i];
557569
let rust_indirect = type_of::arg_is_indirect(ccx, rust_ty);
558-
let llty = rust_param_tys.next().expect("Not enough parameter types!");
570+
let (llforeign_arg_ty, llty) = tys.next().expect("Not enough parameter types!");
559571
let llrust_ty = if rust_indirect {
560572
llty.element_type()
561573
} else {
562574
llty
563575
};
564-
let llforeign_arg_ty = fn_ty.args[i];
565576
let foreign_indirect = llforeign_arg_ty.is_indirect();
566577

567578
if llforeign_arg_ty.is_ignore() {
@@ -574,6 +585,19 @@ pub fn trans_rust_fn_with_foreign_abi<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
574585
let foreign_index = next_foreign_arg(llforeign_arg_ty.pad.is_some());
575586
let mut llforeign_arg = get_param(llwrapfn, foreign_index);
576587

588+
if type_is_fat_ptr(ccx.tcx(), rust_ty) {
589+
// Fat pointers are one pointer and one integer or pointer.
590+
let a = llforeign_arg_ty;
591+
let (b, _) = tys.next().expect("Not enough parameter types!");
592+
assert_eq!((a.cast, b.cast), (None, None));
593+
assert!(!a.is_indirect() && !b.is_indirect());
594+
595+
llrust_args.push(llforeign_arg);
596+
let foreign_index = next_foreign_arg(llforeign_arg_ty.pad.is_some());
597+
llrust_args.push(get_param(llwrapfn, foreign_index));
598+
continue;
599+
}
600+
577601
debug!("llforeign_arg {}{}: {:?}", "#",
578602
i, Value(llforeign_arg));
579603
debug!("rust_indirect = {}, foreign_indirect = {}",
@@ -624,15 +648,7 @@ pub fn trans_rust_fn_with_foreign_abi<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
624648

625649
debug!("llrust_arg {}{}: {:?}", "#",
626650
i, Value(llrust_arg));
627-
if type_is_fat_ptr(ccx.tcx(), rust_ty) {
628-
let next_llrust_ty = rust_param_tys.next().expect("Not enough parameter types!");
629-
llrust_args.push(builder.load(builder.bitcast(builder.struct_gep(
630-
llrust_arg, abi::FAT_PTR_ADDR), llrust_ty.ptr_to())));
631-
llrust_args.push(builder.load(builder.bitcast(builder.struct_gep(
632-
llrust_arg, abi::FAT_PTR_EXTRA), next_llrust_ty.ptr_to())));
633-
} else {
634-
llrust_args.push(llrust_arg);
635-
}
651+
llrust_args.push(llrust_arg);
636652
}
637653

638654
// Perform the call itself

0 commit comments

Comments
 (0)