Skip to content

Instantly share code, notes, and snippets.

@pcwalton
Created September 6, 2016 21:08
Show Gist options
  • Save pcwalton/d39cefac22d66c2f3c0b9c064cf54f1d to your computer and use it in GitHub Desktop.
Save pcwalton/d39cefac22d66c2f3c0b9c064cf54f1d to your computer and use it in GitHub Desktop.
diff --git a/src/librustc_trans/abi.rs b/src/librustc_trans/abi.rs
index 3a7fde6..7df6fbf 100644
--- a/src/librustc_trans/abi.rs
+++ b/src/librustc_trans/abi.rs
@@ -22,7 +22,7 @@ use cabi_powerpc;
use cabi_powerpc64;
use cabi_mips;
use cabi_asmjs;
-use machine::{llalign_of_min, llsize_of, llsize_of_real, llsize_of_store};
+use machine::{llalign_of_min, llsize_of_real, llsize_of_store};
use type_::Type;
use type_of;
@@ -151,15 +151,20 @@ impl ArgType {
/// lvalue for the original Rust type of this argument/return.
/// Can be used for both storing formal arguments into Rust variables
/// or results of call/invoke instructions into their destinations.
- pub fn store(&self, bcx: &BlockAndBuilder, mut val: ValueRef, dst: ValueRef) {
+ pub fn store<'blk, 'tcx>(&self,
+ bcx: &BlockAndBuilder<'blk, 'tcx>,
+ mut val: ValueRef,
+ dst: ValueRef,
+ ty: Ty<'tcx>) {
if self.is_ignore() {
return;
}
let ccx = bcx.ccx();
if self.is_indirect() {
- let llsz = llsize_of(ccx, self.ty);
+ bcx.with_block(|bcx| base::memcpy_ty(bcx, dst, val, ty));
+ /*let llsz = llsize_of(ccx, self.ty);
let llalign = llalign_of_min(ccx, self.ty);
- base::call_memcpy(bcx, dst, val, llsz, llalign as u32);
+ base::call_memcpy(bcx, dst, val, llsz, llalign as u32);*/
} else if let Some(ty) = self.cast {
// FIXME(eddyb): Figure out when the simpler Store is safe, clang
// uses it for i16 -> {i8, i8}, but not for i24 -> {i8, i8, i8}.
@@ -211,7 +216,11 @@ impl ArgType {
}
}
- pub fn store_fn_arg(&self, bcx: &BlockAndBuilder, idx: &mut usize, dst: ValueRef) {
+ pub fn store_fn_arg<'blk, 'tcx>(&self,
+ bcx: &BlockAndBuilder<'blk, 'tcx>,
+ idx: &mut usize,
+ dst: ValueRef,
+ ty: Ty<'tcx>) {
if self.pad.is_some() {
*idx += 1;
}
@@ -220,7 +229,7 @@ impl ArgType {
}
let val = llvm::get_param(bcx.fcx().llfn, *idx as c_uint);
*idx += 1;
- self.store(bcx, val, dst);
+ self.store(bcx, val, dst, ty);
}
}
diff --git a/src/librustc_trans/base.rs b/src/librustc_trans/base.rs
index a183fc0..41bbe4f 100644
--- a/src/librustc_trans/base.rs
+++ b/src/librustc_trans/base.rs
@@ -1011,18 +1011,22 @@ impl<'blk, 'tcx> FunctionContext<'blk, 'tcx> {
/// Ties up the llstaticallocas -> llloadenv -> lltop edges,
/// and builds the return block.
- pub fn finish(&'blk self, ret_cx: Block<'blk, 'tcx>,
+ pub fn finish(&'blk self,
+ ret_cx: Block<'blk, 'tcx>,
+ return_type: Ty<'tcx>,
ret_debug_loc: DebugLoc) {
let _icx = push_ctxt("FunctionContext::finish");
- self.build_return_block(ret_cx, ret_debug_loc);
+ self.build_return_block(ret_cx, return_type, ret_debug_loc);
DebugLoc::None.apply(self);
self.cleanup();
}
// Builds the return block for a function.
- pub fn build_return_block(&self, ret_cx: Block<'blk, 'tcx>,
+ pub fn build_return_block(&self,
+ ret_cx: Block<'blk, 'tcx>,
+ return_type: Ty<'tcx>,
ret_debug_location: DebugLoc) {
if self.llretslotptr.get().is_none() ||
ret_cx.unreachable.get() ||
@@ -1058,10 +1062,11 @@ impl<'blk, 'tcx> FunctionContext<'blk, 'tcx> {
(_, cast_ty) if self.fn_ty.ret.is_indirect() => {
// Otherwise, copy the return value to the ret slot.
assert_eq!(cast_ty, None);
- let llsz = llsize_of(self.ccx, self.fn_ty.ret.ty);
- let llalign = llalign_of_min(self.ccx, self.fn_ty.ret.ty);
- call_memcpy(&B(ret_cx), get_param(self.llfn, 0),
- retslot, llsz, llalign as u32);
+ /*let llsz = llsize_of(self.ccx, self.fn_ty.ret.ty);
+ let llalign = llalign_of_min(self.ccx, self.fn_ty.ret.ty);*/
+ memcpy_ty(ret_cx, get_param(self.llfn, 0), retslot, return_type);
+ /*call_memcpy(&B(ret_cx), get_param(self.llfn, 0),
+ retslot, llsz, llalign as u32);*/
RetVoid(ret_cx, ret_debug_location)
}
(_, Some(cast_ty)) => {
@@ -1177,16 +1182,16 @@ pub fn trans_ctor_shim<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
if common::type_is_fat_ptr(bcx.tcx(), arg_ty) {
let meta = &fcx.fn_ty.args[arg_idx];
arg_idx += 1;
- arg.store_fn_arg(b, &mut llarg_idx, get_dataptr(bcx, lldestptr));
- meta.store_fn_arg(b, &mut llarg_idx, get_meta(bcx, lldestptr));
+ arg.store_fn_arg(b, &mut llarg_idx, get_dataptr(bcx, lldestptr), arg_ty);
+ meta.store_fn_arg(b, &mut llarg_idx, get_meta(bcx, lldestptr), arg_ty);
} else {
- arg.store_fn_arg(b, &mut llarg_idx, lldestptr);
+ arg.store_fn_arg(b, &mut llarg_idx, lldestptr, arg_ty);
}
}
adt::trans_set_discr(bcx, &repr, dest, disr);
}
- fcx.finish(bcx, DebugLoc::None);
+ fcx.finish(bcx, sig.output, DebugLoc::None);
}
pub fn llvm_linkage_by_name(name: &str) -> Option<Linkage> {
diff --git a/src/librustc_trans/callee.rs b/src/librustc_trans/callee.rs
index a30f8f2..3caf541 100644
--- a/src/librustc_trans/callee.rs
+++ b/src/librustc_trans/callee.rs
@@ -340,7 +340,7 @@ pub fn trans_fn_pointer_shim<'a, 'tcx>(
let tuple_fn_ty = tcx.mk_fn_ptr(tcx.mk_bare_fn(ty::BareFnTy {
unsafety: hir::Unsafety::Normal,
abi: Abi::RustCall,
- sig: ty::Binder(sig)
+ sig: ty::Binder(sig.clone())
}));
debug!("tuple_fn_ty: {:?}", tuple_fn_ty);
@@ -377,7 +377,7 @@ pub fn trans_fn_pointer_shim<'a, 'tcx>(
};
bcx = callee.call(bcx, DebugLoc::None, &llargs[(self_idx + 1)..], dest).bcx;
- fcx.finish(bcx, DebugLoc::None);
+ fcx.finish(bcx, sig.output, DebugLoc::None);
ccx.fn_pointer_shims().borrow_mut().insert(bare_fn_ty_maybe_ref, llfn);
@@ -506,6 +506,10 @@ fn trans_call_inner<'a, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
let fn_ret = callee.ty.fn_ret();
let fn_ty = callee.direct_fn_type(ccx, &[]);
+ let tcx = ccx.tcx();
+ let sig = tcx.erase_late_bound_regions(&callee.ty.fn_sig());
+ let sig = tcx.normalize_associated_type(&sig);
+
let mut callee = match callee.data {
NamedTupleConstructor(_) | Intrinsic => {
bug!("{:?} calls should not go through Callee::call", callee);
@@ -556,7 +560,7 @@ fn trans_call_inner<'a, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
// u64.
if !fn_ty.ret.is_indirect() {
if let Some(llretslot) = opt_llretslot {
- fn_ty.ret.store(&bcx.build(), llret, llretslot);
+ fn_ty.ret.store(&bcx.build(), llret, llretslot, sig.output);
}
}
}
diff --git a/src/librustc_trans/closure.rs b/src/librustc_trans/closure.rs
index 842a8fd..ba24022 100644
--- a/src/librustc_trans/closure.rs
+++ b/src/librustc_trans/closure.rs
@@ -251,7 +251,7 @@ fn trans_fn_once_adapter_shim<'a, 'tcx>(
let llonce_fn_ty = tcx.mk_fn_ptr(tcx.mk_bare_fn(ty::BareFnTy {
unsafety: unsafety,
abi: abi,
- sig: ty::Binder(sig)
+ sig: ty::Binder(sig.clone())
}));
// Create the by-value helper.
@@ -276,7 +276,7 @@ fn trans_fn_once_adapter_shim<'a, 'tcx>(
} else {
let scratch = alloc_ty(bcx, closure_ty, "self");
let mut llarg_idx = self_idx;
- env_arg.store_fn_arg(&bcx.build(), &mut llarg_idx, scratch);
+ env_arg.store_fn_arg(&bcx.build(), &mut llarg_idx, scratch, closure_ty);
scratch
};
@@ -310,7 +310,7 @@ fn trans_fn_once_adapter_shim<'a, 'tcx>(
fcx.pop_and_trans_custom_cleanup_scope(bcx, self_scope);
- fcx.finish(bcx, DebugLoc::None);
+ fcx.finish(bcx, sig.output, DebugLoc::None);
lloncefn
}
diff --git a/src/librustc_trans/glue.rs b/src/librustc_trans/glue.rs
index 8d182a9..20ffde4 100644
--- a/src/librustc_trans/glue.rs
+++ b/src/librustc_trans/glue.rs
@@ -262,7 +262,7 @@ pub fn implement_drop_glue<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
// type, so we don't need to explicitly cast the function parameter.
let bcx = make_drop_glue(bcx, get_param(llfn, 0), g);
- fcx.finish(bcx, DebugLoc::None);
+ fcx.finish(bcx, tcx.mk_nil(), DebugLoc::None);
}
fn trans_struct_drop<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
diff --git a/src/librustc_trans/meth.rs b/src/librustc_trans/meth.rs
index 483bc99..54c1f83 100644
--- a/src/librustc_trans/meth.rs
+++ b/src/librustc_trans/meth.rs
@@ -111,7 +111,7 @@ pub fn trans_object_shim<'a, 'tcx>(ccx: &'a CrateContext<'a, 'tcx>,
bcx = callee.call(bcx, DebugLoc::None,
&llargs[fcx.fn_ty.ret.is_indirect() as usize..], dest).bcx;
- fcx.finish(bcx, DebugLoc::None);
+ fcx.finish(bcx, sig.output, DebugLoc::None);
llfn
}
diff --git a/src/librustc_trans/mir/block.rs b/src/librustc_trans/mir/block.rs
index 3ab4290..5e8ea4c 100644
--- a/src/librustc_trans/mir/block.rs
+++ b/src/librustc_trans/mir/block.rs
@@ -896,7 +896,7 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
}
- // Stores the return value of a function call into it's final location.
+ // Stores the return value of a function call into its final location.
fn store_return(&mut self,
bcx: &BlockAndBuilder<'bcx, 'tcx>,
dest: ReturnDest,
@@ -906,7 +906,7 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
match dest {
Nothing => (),
- Store(dst) => ret_ty.store(bcx, op.immediate(), dst),
+ Store(dst) => ret_ty.store(bcx, op.immediate(), dst, op.ty),
IndirectOperand(tmp, index) => {
let op = self.trans_load(bcx, tmp, op.ty);
self.locals[index] = LocalRef::Operand(Some(op));
@@ -917,7 +917,7 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
let tmp = bcx.with_block(|bcx| {
base::alloc_ty(bcx, op.ty, "tmp_ret")
});
- ret_ty.store(bcx, op.immediate(), tmp);
+ ret_ty.store(bcx, op.immediate(), tmp, op.ty);
self.trans_load(bcx, tmp, op.ty)
} else {
op.unpack_if_pair(bcx)
diff --git a/src/librustc_trans/mir/mod.rs b/src/librustc_trans/mir/mod.rs
index 1934f7b..af7cdf0 100644
--- a/src/librustc_trans/mir/mod.rs
+++ b/src/librustc_trans/mir/mod.rs
@@ -373,10 +373,10 @@ fn arg_local_refs<'bcx, 'tcx>(bcx: &BlockAndBuilder<'bcx, 'tcx>,
// they are the two sub-fields of a single aggregate field.
let meta = &fcx.fn_ty.args[idx];
idx += 1;
- arg.store_fn_arg(bcx, &mut llarg_idx, get_dataptr(bcx, dst));
- meta.store_fn_arg(bcx, &mut llarg_idx, get_meta(bcx, dst));
+ arg.store_fn_arg(bcx, &mut llarg_idx, get_dataptr(bcx, dst), tupled_arg_ty);
+ meta.store_fn_arg(bcx, &mut llarg_idx, get_meta(bcx, dst), tupled_arg_ty);
} else {
- arg.store_fn_arg(bcx, &mut llarg_idx, dst);
+ arg.store_fn_arg(bcx, &mut llarg_idx, dst, tupled_arg_ty);
}
bcx.with_block(|bcx| arg_scope.map(|scope| {
@@ -455,12 +455,12 @@ fn arg_local_refs<'bcx, 'tcx>(bcx: &BlockAndBuilder<'bcx, 'tcx>,
// so make an alloca to store them in.
let meta = &fcx.fn_ty.args[idx];
idx += 1;
- arg.store_fn_arg(bcx, &mut llarg_idx, get_dataptr(bcx, lltemp));
- meta.store_fn_arg(bcx, &mut llarg_idx, get_meta(bcx, lltemp));
+ arg.store_fn_arg(bcx, &mut llarg_idx, get_dataptr(bcx, lltemp), arg_ty);
+ meta.store_fn_arg(bcx, &mut llarg_idx, get_meta(bcx, lltemp), arg_ty);
} else {
// otherwise, arg is passed by value, so make a
// temporary and store it there
- arg.store_fn_arg(bcx, &mut llarg_idx, lltemp);
+ arg.store_fn_arg(bcx, &mut llarg_idx, lltemp, arg_ty);
}
lltemp
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment