From 512f344a3b924688903add51ddcc28ea29482a76 Mon Sep 17 00:00:00 2001 From: Oliver Schneider Date: Fri, 21 Oct 2016 13:56:38 +0200 Subject: [PATCH 1/4] don't force allocate for Misc casts --- src/interpreter/mod.rs | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/src/interpreter/mod.rs b/src/interpreter/mod.rs index 5459ad2f03..790c73385b 100644 --- a/src/interpreter/mod.rs +++ b/src/interpreter/mod.rs @@ -652,13 +652,12 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> { } Cast(kind, ref operand, cast_ty) => { - // FIXME(solson) - let dest = self.force_allocation(dest)?.to_ptr(); - debug_assert_eq!(self.monomorphize(cast_ty, self.substs()), dest_ty); use rustc::mir::repr::CastKind::*; match kind { Unsize => { + // FIXME(solson) + let dest = self.force_allocation(dest)?.to_ptr(); let src = self.eval_operand(operand)?; let src_ty = self.operand_ty(operand); self.unsize_into(src, src_ty, dest, dest_ty)?; @@ -669,32 +668,27 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> { let src_ty = self.operand_ty(operand); if self.type_is_fat_ptr(src_ty) { trace!("misc cast: {:?}", src); - let ptr_size = self.memory.pointer_size(); match (src, self.type_is_fat_ptr(dest_ty)) { - (Value::ByValPair(data, meta), true) => { - self.memory.write_primval(dest, data)?; - self.memory.write_primval(dest.offset(ptr_size as isize), meta)?; + (Value::ByRef(_), _) | + (Value::ByValPair(..), true) => { + self.write_value(src, dest, dest_ty)?; }, (Value::ByValPair(data, _), false) => { - self.memory.write_primval(dest, data)?; - }, - (Value::ByRef(ptr), true) => { - self.memory.copy(ptr, dest, ptr_size * 2, ptr_size)?; - }, - (Value::ByRef(ptr), false) => { - self.memory.copy(ptr, dest, ptr_size, ptr_size)?; + self.write_value(Value::ByVal(data), dest, dest_ty)?; }, (Value::ByVal(_), _) => bug!("expected fat ptr"), } } else { let src_val = self.value_to_primval(src, src_ty)?; let dest_val = self.cast_primval(src_val, dest_ty)?; - self.memory.write_primval(dest, dest_val)?; + self.write_value(Value::ByVal(dest_val), dest, dest_ty)?; } } ReifyFnPointer => match self.operand_ty(operand).sty { ty::TyFnDef(def_id, substs, fn_ty) => { + // FIXME(solson) + let dest = self.force_allocation(dest)?.to_ptr(); let fn_ptr = self.memory.create_fn_ptr(def_id, substs, fn_ty); self.memory.write_ptr(dest, fn_ptr)?; }, @@ -703,6 +697,8 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> { UnsafeFnPointer => match dest_ty.sty { ty::TyFnPtr(unsafe_fn_ty) => { + // FIXME(solson) + let dest = self.force_allocation(dest)?.to_ptr(); let src = self.eval_operand(operand)?; let ptr = src.read_ptr(&self.memory)?; let (def_id, substs, _) = self.memory.get_fn(ptr.alloc_id)?; From eb08a2e64618faa3d4af5d1a687de1c3c13c2c6b Mon Sep 17 00:00:00 2001 From: Oliver Schneider Date: Fri, 21 Oct 2016 14:54:37 +0200 Subject: [PATCH 2/4] don't force allocate for ReifyFnPointer casts --- src/interpreter/mod.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/interpreter/mod.rs b/src/interpreter/mod.rs index 790c73385b..96e0c00737 100644 --- a/src/interpreter/mod.rs +++ b/src/interpreter/mod.rs @@ -687,10 +687,8 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> { ReifyFnPointer => match self.operand_ty(operand).sty { ty::TyFnDef(def_id, substs, fn_ty) => { - // FIXME(solson) - let dest = self.force_allocation(dest)?.to_ptr(); let fn_ptr = self.memory.create_fn_ptr(def_id, substs, fn_ty); - self.memory.write_ptr(dest, fn_ptr)?; + self.write_value(Value::ByVal(PrimVal::from_fn_ptr(fn_ptr)), dest, dest_ty)?; }, ref other => bug!("reify fn pointer on {:?}", other), }, From 9af5a0a420009d9b79709b6fbccdf2288a5517fb Mon Sep 17 00:00:00 2001 From: Oliver Schneider Date: Fri, 21 Oct 2016 14:55:49 +0200 Subject: [PATCH 3/4] don't force allocate for UnsafeFnPointer casts --- src/interpreter/mod.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/interpreter/mod.rs b/src/interpreter/mod.rs index 96e0c00737..902da52868 100644 --- a/src/interpreter/mod.rs +++ b/src/interpreter/mod.rs @@ -695,13 +695,11 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> { UnsafeFnPointer => match dest_ty.sty { ty::TyFnPtr(unsafe_fn_ty) => { - // FIXME(solson) - let dest = self.force_allocation(dest)?.to_ptr(); let src = self.eval_operand(operand)?; let ptr = src.read_ptr(&self.memory)?; let (def_id, substs, _) = self.memory.get_fn(ptr.alloc_id)?; let fn_ptr = self.memory.create_fn_ptr(def_id, substs, unsafe_fn_ty); - self.memory.write_ptr(dest, fn_ptr)?; + self.write_value(Value::ByVal(PrimVal::from_fn_ptr(fn_ptr)), dest, dest_ty)?; }, ref other => bug!("fn to unsafe fn cast on {:?}", other), }, From 073f91654c5ac9d9a18e872ca340e9fd13d61d39 Mon Sep 17 00:00:00 2001 From: Oliver Schneider Date: Fri, 21 Oct 2016 15:18:12 +0200 Subject: [PATCH 4/4] don't force allocate for most Unsize casts only Arc -> Arc unsize casts are left --- src/interpreter/mod.rs | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/src/interpreter/mod.rs b/src/interpreter/mod.rs index 902da52868..c7e5e12794 100644 --- a/src/interpreter/mod.rs +++ b/src/interpreter/mod.rs @@ -656,8 +656,6 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> { use rustc::mir::repr::CastKind::*; match kind { Unsize => { - // FIXME(solson) - let dest = self.force_allocation(dest)?.to_ptr(); let src = self.eval_operand(operand)?; let src_ty = self.operand_ty(operand); self.unsize_into(src, src_ty, dest, dest_ty)?; @@ -1484,7 +1482,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> { &mut self, src: Value, src_ty: Ty<'tcx>, - dest: Pointer, + dest: Lvalue<'tcx>, dest_ty: Ty<'tcx>, ) -> EvalResult<'tcx, ()> { match (&src_ty.sty, &dest_ty.sty) { @@ -1498,33 +1496,32 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> { match (&src_pointee_ty.sty, &dest_pointee_ty.sty) { (&ty::TyArray(_, length), &ty::TySlice(_)) => { let ptr = src.read_ptr(&self.memory)?; - self.memory.write_ptr(dest, ptr)?; - let ptr_size = self.memory.pointer_size() as isize; - let dest_extra = dest.offset(ptr_size); - self.memory.write_usize(dest_extra, length as u64)?; + let len = self.usize_primval(length as u64); + let ptr = PrimVal::from_ptr(ptr); + self.write_value(Value::ByValPair(ptr, len), dest, dest_ty)?; } (&ty::TyTrait(_), &ty::TyTrait(_)) => { // For now, upcasts are limited to changes in marker // traits, and hence never actually require an actual // change to the vtable. - self.write_value_to_ptr(src, dest, dest_ty)?; + self.write_value(src, dest, dest_ty)?; }, (_, &ty::TyTrait(ref data)) => { let trait_ref = data.principal.with_self_ty(self.tcx, src_pointee_ty); let trait_ref = self.tcx.erase_regions(&trait_ref); let vtable = self.get_vtable(trait_ref)?; let ptr = src.read_ptr(&self.memory)?; - - self.memory.write_ptr(dest, ptr)?; - let ptr_size = self.memory.pointer_size() as isize; - let dest_extra = dest.offset(ptr_size); - self.memory.write_ptr(dest_extra, vtable)?; + let ptr = PrimVal::from_ptr(ptr); + let extra = PrimVal::from_ptr(vtable); + self.write_value(Value::ByValPair(ptr, extra), dest, dest_ty)?; }, _ => bug!("invalid unsizing {:?} -> {:?}", src_ty, dest_ty), } } (&ty::TyAdt(def_a, substs_a), &ty::TyAdt(def_b, substs_b)) => { + // FIXME(solson) + let dest = self.force_allocation(dest)?.to_ptr(); // unsizing of generic struct with pointer fields // Example: `Arc` -> `Arc` // here we need to increase the size of every &T thin ptr field to a fat ptr @@ -1555,7 +1552,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> { if src_fty == dst_fty { self.copy(src_f_ptr, dst_f_ptr, src_fty)?; } else { - self.unsize_into(Value::ByRef(src_f_ptr), src_fty, dst_f_ptr, dst_fty)?; + self.unsize_into(Value::ByRef(src_f_ptr), src_fty, Lvalue::from_ptr(dst_f_ptr), dst_fty)?; } } }