Skip to content

Commit c148d88

Browse files
authored
Merge pull request rust-lang#69 from oli-obk/master
don't force allocations for most casts
2 parents 7f3cb7f + 073f916 commit c148d88

File tree

1 file changed

+18
-29
lines changed

1 file changed

+18
-29
lines changed

src/interpreter/mod.rs

+18-29
Original file line numberDiff line numberDiff line change
@@ -652,9 +652,6 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
652652
}
653653

654654
Cast(kind, ref operand, cast_ty) => {
655-
// FIXME(solson)
656-
let dest = self.force_allocation(dest)?.to_ptr();
657-
658655
debug_assert_eq!(self.monomorphize(cast_ty, self.substs()), dest_ty);
659656
use rustc::mir::repr::CastKind::*;
660657
match kind {
@@ -669,34 +666,27 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
669666
let src_ty = self.operand_ty(operand);
670667
if self.type_is_fat_ptr(src_ty) {
671668
trace!("misc cast: {:?}", src);
672-
let ptr_size = self.memory.pointer_size();
673669
match (src, self.type_is_fat_ptr(dest_ty)) {
674-
(Value::ByValPair(data, meta), true) => {
675-
self.memory.write_primval(dest, data)?;
676-
self.memory.write_primval(dest.offset(ptr_size as isize), meta)?;
670+
(Value::ByRef(_), _) |
671+
(Value::ByValPair(..), true) => {
672+
self.write_value(src, dest, dest_ty)?;
677673
},
678674
(Value::ByValPair(data, _), false) => {
679-
self.memory.write_primval(dest, data)?;
680-
},
681-
(Value::ByRef(ptr), true) => {
682-
self.memory.copy(ptr, dest, ptr_size * 2, ptr_size)?;
683-
},
684-
(Value::ByRef(ptr), false) => {
685-
self.memory.copy(ptr, dest, ptr_size, ptr_size)?;
675+
self.write_value(Value::ByVal(data), dest, dest_ty)?;
686676
},
687677
(Value::ByVal(_), _) => bug!("expected fat ptr"),
688678
}
689679
} else {
690680
let src_val = self.value_to_primval(src, src_ty)?;
691681
let dest_val = self.cast_primval(src_val, dest_ty)?;
692-
self.memory.write_primval(dest, dest_val)?;
682+
self.write_value(Value::ByVal(dest_val), dest, dest_ty)?;
693683
}
694684
}
695685

696686
ReifyFnPointer => match self.operand_ty(operand).sty {
697687
ty::TyFnDef(def_id, substs, fn_ty) => {
698688
let fn_ptr = self.memory.create_fn_ptr(def_id, substs, fn_ty);
699-
self.memory.write_ptr(dest, fn_ptr)?;
689+
self.write_value(Value::ByVal(PrimVal::from_fn_ptr(fn_ptr)), dest, dest_ty)?;
700690
},
701691
ref other => bug!("reify fn pointer on {:?}", other),
702692
},
@@ -707,7 +697,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
707697
let ptr = src.read_ptr(&self.memory)?;
708698
let (def_id, substs, _) = self.memory.get_fn(ptr.alloc_id)?;
709699
let fn_ptr = self.memory.create_fn_ptr(def_id, substs, unsafe_fn_ty);
710-
self.memory.write_ptr(dest, fn_ptr)?;
700+
self.write_value(Value::ByVal(PrimVal::from_fn_ptr(fn_ptr)), dest, dest_ty)?;
711701
},
712702
ref other => bug!("fn to unsafe fn cast on {:?}", other),
713703
},
@@ -1492,7 +1482,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
14921482
&mut self,
14931483
src: Value,
14941484
src_ty: Ty<'tcx>,
1495-
dest: Pointer,
1485+
dest: Lvalue<'tcx>,
14961486
dest_ty: Ty<'tcx>,
14971487
) -> EvalResult<'tcx, ()> {
14981488
match (&src_ty.sty, &dest_ty.sty) {
@@ -1506,33 +1496,32 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
15061496
match (&src_pointee_ty.sty, &dest_pointee_ty.sty) {
15071497
(&ty::TyArray(_, length), &ty::TySlice(_)) => {
15081498
let ptr = src.read_ptr(&self.memory)?;
1509-
self.memory.write_ptr(dest, ptr)?;
1510-
let ptr_size = self.memory.pointer_size() as isize;
1511-
let dest_extra = dest.offset(ptr_size);
1512-
self.memory.write_usize(dest_extra, length as u64)?;
1499+
let len = self.usize_primval(length as u64);
1500+
let ptr = PrimVal::from_ptr(ptr);
1501+
self.write_value(Value::ByValPair(ptr, len), dest, dest_ty)?;
15131502
}
15141503
(&ty::TyTrait(_), &ty::TyTrait(_)) => {
15151504
// For now, upcasts are limited to changes in marker
15161505
// traits, and hence never actually require an actual
15171506
// change to the vtable.
1518-
self.write_value_to_ptr(src, dest, dest_ty)?;
1507+
self.write_value(src, dest, dest_ty)?;
15191508
},
15201509
(_, &ty::TyTrait(ref data)) => {
15211510
let trait_ref = data.principal.with_self_ty(self.tcx, src_pointee_ty);
15221511
let trait_ref = self.tcx.erase_regions(&trait_ref);
15231512
let vtable = self.get_vtable(trait_ref)?;
15241513
let ptr = src.read_ptr(&self.memory)?;
1525-
1526-
self.memory.write_ptr(dest, ptr)?;
1527-
let ptr_size = self.memory.pointer_size() as isize;
1528-
let dest_extra = dest.offset(ptr_size);
1529-
self.memory.write_ptr(dest_extra, vtable)?;
1514+
let ptr = PrimVal::from_ptr(ptr);
1515+
let extra = PrimVal::from_ptr(vtable);
1516+
self.write_value(Value::ByValPair(ptr, extra), dest, dest_ty)?;
15301517
},
15311518

15321519
_ => bug!("invalid unsizing {:?} -> {:?}", src_ty, dest_ty),
15331520
}
15341521
}
15351522
(&ty::TyAdt(def_a, substs_a), &ty::TyAdt(def_b, substs_b)) => {
1523+
// FIXME(solson)
1524+
let dest = self.force_allocation(dest)?.to_ptr();
15361525
// unsizing of generic struct with pointer fields
15371526
// Example: `Arc<T>` -> `Arc<Trait>`
15381527
// here we need to increase the size of every &T thin ptr field to a fat ptr
@@ -1563,7 +1552,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
15631552
if src_fty == dst_fty {
15641553
self.copy(src_f_ptr, dst_f_ptr, src_fty)?;
15651554
} else {
1566-
self.unsize_into(Value::ByRef(src_f_ptr), src_fty, dst_f_ptr, dst_fty)?;
1555+
self.unsize_into(Value::ByRef(src_f_ptr), src_fty, Lvalue::from_ptr(dst_f_ptr), dst_fty)?;
15671556
}
15681557
}
15691558
}

0 commit comments

Comments
 (0)