self.log(0, || print!("{:?}", stmt));
let mir::StatementKind::Assign(ref lvalue, ref rvalue) = stmt.kind;
let result = self.eval_assignment(lvalue, rvalue);
- try!(self.maybe_report(stmt.span, result));
+ self.maybe_report(stmt.span, result)?;
}
let terminator = block_data.terminator();
self.log(0, || print!("{:?}", terminator.kind));
let result = self.eval_terminator(terminator);
- match try!(self.maybe_report(terminator.span, result)) {
+ match self.maybe_report(terminator.span, result)? {
TerminatorTarget::Block(block) => current_block = block,
TerminatorTarget::Return => {
self.pop_stack_frame();
let substs = nested_fecx.substs();
nested_fecx.push_stack_frame(CachedMir::Ref(mir), substs, return_ptr);
- try!(nested_fecx.run());
+ nested_fecx.run()?;
Ok(return_ptr)
}
Goto { target } => TerminatorTarget::Block(target),
If { ref cond, targets: (then_target, else_target) } => {
- let cond_ptr = try!(self.eval_operand(cond));
- let cond_val = try!(self.memory.read_bool(cond_ptr));
+ let cond_ptr = self.eval_operand(cond)?;
+ let cond_val = self.memory.read_bool(cond_ptr)?;
TerminatorTarget::Block(if cond_val { then_target } else { else_target })
}
SwitchInt { ref discr, ref values, ref targets, .. } => {
- let discr_ptr = try!(self.eval_lvalue(discr)).to_ptr();
+ let discr_ptr = self.eval_lvalue(discr)?.to_ptr();
let discr_size = self
.type_layout(self.lvalue_ty(discr))
.size(&self.tcx.data_layout)
.bytes() as usize;
- let discr_val = try!(self.memory.read_uint(discr_ptr, discr_size));
+ let discr_val = self.memory.read_uint(discr_ptr, discr_size)?;
// Branch to the `otherwise` case by default, if no match is found.
let mut target_block = targets[targets.len() - 1];
for (index, val_const) in values.iter().enumerate() {
- let ptr = try!(self.const_to_ptr(val_const));
- let val = try!(self.memory.read_uint(ptr, discr_size));
+ let ptr = self.const_to_ptr(val_const)?;
+ let val = self.memory.read_uint(ptr, discr_size)?;
if discr_val == val {
target_block = targets[index];
break;
}
Switch { ref discr, ref targets, adt_def } => {
- let adt_ptr = try!(self.eval_lvalue(discr)).to_ptr();
+ let adt_ptr = self.eval_lvalue(discr)?.to_ptr();
let adt_layout = self.type_layout(self.lvalue_ty(discr));
match *adt_layout {
Layout::General { discr, .. } | Layout::CEnum { discr, .. } => {
let discr_size = discr.size().bytes();
- let discr_val = try!(self.memory.read_uint(adt_ptr, discr_size as usize));
+ let discr_val = self.memory.read_uint(adt_ptr, discr_size as usize)?;
let matching = adt_def.variants.iter()
.position(|v| discr_val == v.disr_val.to_u64_unchecked());
let mut return_ptr = None;
if let Some((ref lv, target)) = *destination {
self.frame_mut().next_block = target;
- return_ptr = Some(try!(self.eval_lvalue(lv)).to_ptr());
+ return_ptr = Some(self.eval_lvalue(lv)?.to_ptr());
}
let func_ty = self.operand_ty(func);
match fn_ty.sig.0.output {
ty::FnConverging(ty) => {
let size = self.type_size(ty);
- try!(self.call_intrinsic(&name, substs, args,
- return_ptr.unwrap(), size))
+ self.call_intrinsic(&name, substs, args,
+ return_ptr.unwrap(), size)?
}
ty::FnDiverging => unimplemented!(),
}
}
- Abi::C =>
- try!(self.call_c_abi(def_id, args, return_ptr.unwrap())),
+ Abi::C => self.call_c_abi(def_id, args, return_ptr.unwrap())?,
Abi::Rust | Abi::RustCall => {
// TODO(tsion): Adjust the first argument when calling a Fn or
let mut arg_srcs = Vec::new();
for arg in args {
- let src = try!(self.eval_operand(arg));
+ let src = self.eval_operand(arg)?;
let src_ty = self.operand_ty(arg);
arg_srcs.push((src, src_ty));
}
if fn_ty.abi == Abi::RustCall && !args.is_empty() {
arg_srcs.pop();
let last_arg = args.last().unwrap();
- let last = try!(self.eval_operand(last_arg));
+ let last = self.eval_operand(last_arg)?;
let last_ty = self.operand_ty(last_arg);
let last_layout = self.type_layout(last_ty);
match (&last_ty.sty, last_layout) {
for (i, (src, src_ty)) in arg_srcs.into_iter().enumerate() {
let dest = self.frame().locals[i];
- try!(self.move_(src, dest, src_ty));
+ self.move_(src, dest, src_ty)?;
}
TerminatorTarget::Call
}
Drop { ref value, target, .. } => {
- let ptr = try!(self.eval_lvalue(value)).to_ptr();
+ let ptr = self.eval_lvalue(value)?.to_ptr();
let ty = self.lvalue_ty(value);
- try!(self.drop(ptr, ty));
+ self.drop(ptr, ty)?;
TerminatorTarget::Block(target)
}
ty::TyBox(contents_ty) => {
match self.memory.read_ptr(ptr) {
Ok(contents_ptr) => {
- try!(self.drop(contents_ptr, contents_ty));
+ self.drop(contents_ptr, contents_ty)?;
self.log(1, || print!("deallocating box"));
- try!(self.memory.deallocate(contents_ptr));
+ self.memory.deallocate(contents_ptr)?;
}
Err(EvalError::ReadBytesAsPointer) => {
let size = self.memory.pointer_size;
- let possible_drop_fill = try!(self.memory.read_bytes(ptr, size));
+ let possible_drop_fill = self.memory.read_bytes(ptr, size)?;
if possible_drop_fill.iter().all(|&b| b == mem::POST_DROP_U8) {
return Ok(());
} else {
// Filling drop.
// FIXME(tsion): Trait objects (with no static size) probably get filled, too.
let size = self.type_size(ty);
- try!(self.memory.drop_fill(ptr, size));
+ self.memory.drop_fill(ptr, size)?;
Ok(())
}
let args_res: EvalResult<Vec<Pointer>> = args.iter()
.map(|arg| self.eval_operand(arg))
.collect();
- let args = try!(args_res);
+ let args = args_res?;
match name {
"assume" => {}
"copy_nonoverlapping" => {
let elem_ty = *substs.types.get(subst::FnSpace, 0);
let elem_size = self.type_size(elem_ty);
- let src = try!(self.memory.read_ptr(args[0]));
- let dest = try!(self.memory.read_ptr(args[1]));
- let count = try!(self.memory.read_isize(args[2]));
- try!(self.memory.copy(src, dest, count as usize * elem_size));
+ let src = self.memory.read_ptr(args[0])?;
+ let dest = self.memory.read_ptr(args[1])?;
+ let count = self.memory.read_isize(args[2])?;
+ self.memory.copy(src, dest, count as usize * elem_size)?;
}
"forget" => {
let arg_ty = *substs.types.get(subst::FnSpace, 0);
let arg_size = self.type_size(arg_ty);
- try!(self.memory.drop_fill(args[0], arg_size));
+ self.memory.drop_fill(args[0], arg_size)?;
}
- "init" => try!(self.memory.write_repeat(dest, 0, dest_size)),
+ "init" => self.memory.write_repeat(dest, 0, dest_size)?,
"min_align_of" => {
- try!(self.memory.write_int(dest, 1, dest_size));
+ self.memory.write_int(dest, 1, dest_size)?;
}
"move_val_init" => {
let ty = *substs.types.get(subst::FnSpace, 0);
- let ptr = try!(self.memory.read_ptr(args[0]));
- try!(self.move_(args[1], ptr, ty));
+ let ptr = self.memory.read_ptr(args[0])?;
+ self.move_(args[1], ptr, ty)?;
}
// FIXME(tsion): Handle different integer types correctly.
"add_with_overflow" => {
let ty = *substs.types.get(subst::FnSpace, 0);
let size = self.type_size(ty);
- let left = try!(self.memory.read_int(args[0], size));
- let right = try!(self.memory.read_int(args[1], size));
+ let left = self.memory.read_int(args[0], size)?;
+ let right = self.memory.read_int(args[1], size)?;
let (n, overflowed) = unsafe {
::std::intrinsics::add_with_overflow::<i64>(left, right)
};
- try!(self.memory.write_int(dest, n, size));
- try!(self.memory.write_bool(dest.offset(size as isize), overflowed));
+ self.memory.write_int(dest, n, size)?;
+ self.memory.write_bool(dest.offset(size as isize), overflowed)?;
}
// FIXME(tsion): Handle different integer types correctly.
"mul_with_overflow" => {
let ty = *substs.types.get(subst::FnSpace, 0);
let size = self.type_size(ty);
- let left = try!(self.memory.read_int(args[0], size));
- let right = try!(self.memory.read_int(args[1], size));
+ let left = self.memory.read_int(args[0], size)?;
+ let right = self.memory.read_int(args[1], size)?;
let (n, overflowed) = unsafe {
::std::intrinsics::mul_with_overflow::<i64>(left, right)
};
- try!(self.memory.write_int(dest, n, size));
- try!(self.memory.write_bool(dest.offset(size as isize), overflowed));
+ self.memory.write_int(dest, n, size)?;
+ self.memory.write_bool(dest.offset(size as isize), overflowed)?;
}
"offset" => {
let pointee_ty = *substs.types.get(subst::FnSpace, 0);
let pointee_size = self.type_size(pointee_ty) as isize;
let ptr_arg = args[0];
- let offset = try!(self.memory.read_isize(args[1]));
+ let offset = self.memory.read_isize(args[1])?;
match self.memory.read_ptr(ptr_arg) {
Ok(ptr) => {
let result_ptr = ptr.offset(offset as isize * pointee_size);
- try!(self.memory.write_ptr(dest, result_ptr));
+ self.memory.write_ptr(dest, result_ptr)?;
}
Err(EvalError::ReadBytesAsPointer) => {
- let addr = try!(self.memory.read_isize(ptr_arg));
+ let addr = self.memory.read_isize(ptr_arg)?;
let result_addr = addr + offset * pointee_size as i64;
- try!(self.memory.write_isize(dest, result_addr));
+ self.memory.write_isize(dest, result_addr)?;
}
Err(e) => return Err(e),
}
"overflowing_sub" => {
let ty = *substs.types.get(subst::FnSpace, 0);
let size = self.type_size(ty);
- let left = try!(self.memory.read_int(args[0], size));
- let right = try!(self.memory.read_int(args[1], size));
+ let left = self.memory.read_int(args[0], size)?;
+ let right = self.memory.read_int(args[1], size)?;
let n = left.wrapping_sub(right);
- try!(self.memory.write_int(dest, n, size));
+ self.memory.write_int(dest, n, size)?;
}
"size_of" => {
let ty = *substs.types.get(subst::FnSpace, 0);
let size = self.type_size(ty) as u64;
- try!(self.memory.write_uint(dest, size, dest_size));
+ self.memory.write_uint(dest, size, dest_size)?;
}
"transmute" => {
let ty = *substs.types.get(subst::FnSpace, 0);
- try!(self.move_(args[0], dest, ty));
+ self.move_(args[0], dest, ty)?;
}
- "uninit" => try!(self.memory.mark_definedness(dest, dest_size, false)),
+ "uninit" => self.memory.mark_definedness(dest, dest_size, false)?,
name => panic!("can't handle intrinsic: {}", name),
}
let args_res: EvalResult<Vec<Pointer>> = args.iter()
.map(|arg| self.eval_operand(arg))
.collect();
- let args = try!(args_res);
+ let args = args_res?;
match &link_name[..] {
"__rust_allocate" => {
- let size = try!(self.memory.read_usize(args[0]));
+ let size = self.memory.read_usize(args[0])?;
let ptr = self.memory.allocate(size as usize);
- try!(self.memory.write_ptr(dest, ptr));
+ self.memory.write_ptr(dest, ptr)?;
}
"__rust_reallocate" => {
- let ptr = try!(self.memory.read_ptr(args[0]));
- let size = try!(self.memory.read_usize(args[2]));
- try!(self.memory.reallocate(ptr, size as usize));
- try!(self.memory.write_ptr(dest, ptr));
+ let ptr = self.memory.read_ptr(args[0])?;
+ let size = self.memory.read_usize(args[2])?;
+ self.memory.reallocate(ptr, size as usize)?;
+ self.memory.write_ptr(dest, ptr)?;
}
_ => panic!("can't call C ABI function: {}", link_name),
operands: &[mir::Operand<'tcx>],
) -> EvalResult<()> {
for (offset, operand) in offsets.into_iter().zip(operands) {
- let src = try!(self.eval_operand(operand));
+ let src = self.eval_operand(operand)?;
let src_ty = self.operand_ty(operand);
let field_dest = dest.offset(offset as isize);
- try!(self.move_(src, field_dest, src_ty));
+ self.move_(src, field_dest, src_ty)?;
}
Ok(())
}
fn eval_assignment(&mut self, lvalue: &mir::Lvalue<'tcx>, rvalue: &mir::Rvalue<'tcx>)
-> EvalResult<()>
{
- let dest = try!(self.eval_lvalue(lvalue)).to_ptr();
+ let dest = self.eval_lvalue(lvalue)?.to_ptr();
let dest_ty = self.lvalue_ty(lvalue);
let dest_layout = self.type_layout(dest_ty);
use rustc::mir::repr::Rvalue::*;
match *rvalue {
Use(ref operand) => {
- let src = try!(self.eval_operand(operand));
- try!(self.move_(src, dest, dest_ty));
+ let src = self.eval_operand(operand)?;
+ self.move_(src, dest, dest_ty)?;
}
BinaryOp(bin_op, ref left, ref right) => {
- let left_ptr = try!(self.eval_operand(left));
+ let left_ptr = self.eval_operand(left)?;
let left_ty = self.operand_ty(left);
- let left_val = try!(self.read_primval(left_ptr, left_ty));
+ let left_val = self.read_primval(left_ptr, left_ty)?;
- let right_ptr = try!(self.eval_operand(right));
+ let right_ptr = self.eval_operand(right)?;
let right_ty = self.operand_ty(right);
- let right_val = try!(self.read_primval(right_ptr, right_ty));
+ let right_val = self.read_primval(right_ptr, right_ty)?;
- let val = try!(primval::binary_op(bin_op, left_val, right_val));
- try!(self.memory.write_primval(dest, val));
+ let val = primval::binary_op(bin_op, left_val, right_val)?;
+ self.memory.write_primval(dest, val)?;
}
UnaryOp(un_op, ref operand) => {
- let ptr = try!(self.eval_operand(operand));
+ let ptr = self.eval_operand(operand)?;
let ty = self.operand_ty(operand);
- let val = try!(self.read_primval(ptr, ty));
- try!(self.memory.write_primval(dest, primval::unary_op(un_op, val)));
+ let val = self.read_primval(ptr, ty)?;
+ self.memory.write_primval(dest, primval::unary_op(un_op, val))?;
}
Aggregate(ref kind, ref operands) => {
Univariant { ref variant, .. } => {
let offsets = iter::once(0)
.chain(variant.offset_after_field.iter().map(|s| s.bytes()));
- try!(self.assign_fields(dest, offsets, operands));
+ self.assign_fields(dest, offsets, operands)?;
}
Array { .. } => {
kind, dest_ty),
};
let offsets = (0..).map(|i| i * elem_size);
- try!(self.assign_fields(dest, offsets, operands));
+ self.assign_fields(dest, offsets, operands)?;
}
General { discr, ref variants, .. } => {
if let mir::AggregateKind::Adt(adt_def, variant, _) = *kind {
let discr_val = adt_def.variants[variant].disr_val.to_u64_unchecked();
let discr_size = discr.size().bytes() as usize;
- try!(self.memory.write_uint(dest, discr_val, discr_size));
+ self.memory.write_uint(dest, discr_val, discr_size)?;
let offsets = variants[variant].offset_after_field.iter()
.map(|s| s.bytes());
- try!(self.assign_fields(dest, offsets, operands));
+ self.assign_fields(dest, offsets, operands)?;
} else {
panic!("tried to assign {:?} to Layout::General", kind);
}
if nndiscr == variant as u64 {
assert_eq!(operands.len(), 1);
let operand = &operands[0];
- let src = try!(self.eval_operand(operand));
+ let src = self.eval_operand(operand)?;
let src_ty = self.operand_ty(operand);
- try!(self.move_(src, dest, src_ty));
+ self.move_(src, dest, src_ty)?;
} else {
assert_eq!(operands.len(), 0);
- try!(self.memory.write_isize(dest, 0));
+ self.memory.write_isize(dest, 0)?;
}
} else {
panic!("tried to assign {:?} to Layout::RawNullablePointer", kind);
let size = discr.size().bytes() as usize;
if signed {
- try!(self.memory.write_int(dest, val as i64, size));
+ self.memory.write_int(dest, val as i64, size)?;
} else {
- try!(self.memory.write_uint(dest, val, size));
+ self.memory.write_uint(dest, val, size)?;
}
} else {
panic!("tried to assign {:?} to Layout::CEnum", kind);
_ => panic!("tried to assign array-repeat to non-array type {:?}", dest_ty),
};
- let src = try!(self.eval_operand(operand));
+ let src = self.eval_operand(operand)?;
for i in 0..length {
let elem_dest = dest.offset((i * elem_size) as isize);
- try!(self.memory.copy(src, elem_dest, elem_size));
+ self.memory.copy(src, elem_dest, elem_size)?;
}
}
Len(ref lvalue) => {
- let src = try!(self.eval_lvalue(lvalue));
+ let src = self.eval_lvalue(lvalue)?;
let ty = self.lvalue_ty(lvalue);
let len = match ty.sty {
ty::TyArray(_, n) => n as u64,
},
_ => panic!("Rvalue::Len expected array or slice, got {:?}", ty),
};
- try!(self.memory.write_usize(dest, len));
+ self.memory.write_usize(dest, len)?;
}
Ref(_, _, ref lvalue) => {
- let lv = try!(self.eval_lvalue(lvalue));
- try!(self.memory.write_ptr(dest, lv.ptr));
+ let lv = self.eval_lvalue(lvalue)?;
+ self.memory.write_ptr(dest, lv.ptr)?;
match lv.extra {
LvalueExtra::None => {},
LvalueExtra::Length(len) => {
let len_ptr = dest.offset(self.memory.pointer_size as isize);
- try!(self.memory.write_usize(len_ptr, len));
+ self.memory.write_usize(len_ptr, len)?;
}
LvalueExtra::DowncastVariant(..) =>
panic!("attempted to take a reference to an enum downcast lvalue"),
Box(ty) => {
let size = self.type_size(ty);
let ptr = self.memory.allocate(size);
- try!(self.memory.write_ptr(dest, ptr));
+ self.memory.write_ptr(dest, ptr)?;
}
Cast(kind, ref operand, dest_ty) => {
- let src = try!(self.eval_operand(operand));
+ let src = self.eval_operand(operand)?;
let src_ty = self.operand_ty(operand);
use rustc::mir::repr::CastKind::*;
match kind {
Unsize => {
- try!(self.move_(src, dest, src_ty));
+ self.move_(src, dest, src_ty)?;
let src_pointee_ty = pointee_type(src_ty).unwrap();
let dest_pointee_ty = pointee_type(dest_ty).unwrap();
match (&src_pointee_ty.sty, &dest_pointee_ty.sty) {
(&ty::TyArray(_, length), &ty::TySlice(_)) => {
let len_ptr = dest.offset(self.memory.pointer_size as isize);
- try!(self.memory.write_usize(len_ptr, length as u64));
+ self.memory.write_usize(len_ptr, length as u64)?;
}
_ => panic!("can't handle cast: {:?}", rvalue),
Misc => {
// FIXME(tsion): Wrong for almost everything.
let size = dest_layout.size(&self.tcx.data_layout).bytes() as usize;
- try!(self.memory.copy(src, dest, size));
+ self.memory.copy(src, dest, size)?;
}
_ => panic!("can't handle cast: {:?}", rvalue),
fn eval_operand(&mut self, op: &mir::Operand<'tcx>) -> EvalResult<Pointer> {
use rustc::mir::repr::Operand::*;
match *op {
- Consume(ref lvalue) =>
- Ok(try!(self.eval_lvalue(lvalue)).to_ptr()),
+ Consume(ref lvalue) => Ok(self.eval_lvalue(lvalue)?.to_ptr()),
Constant(mir::Constant { ref literal, .. }) => {
use rustc::mir::repr::Literal::*;
match *literal {
- Value { ref value } => Ok(try!(self.const_to_ptr(value))),
+ Value { ref value } => Ok(self.const_to_ptr(value)?),
Item { .. } => unimplemented!(),
Promoted { index } => {
let current_mir = self.mir();
Static(_def_id) => unimplemented!(),
Projection(ref proj) => {
- let base = try!(self.eval_lvalue(&proj.base));
+ let base = self.eval_lvalue(&proj.base)?;
let base_ty = self.lvalue_ty(&proj.base);
let base_layout = self.type_layout(base_ty);
Deref => {
let pointee_ty = pointee_type(base_ty).expect("Deref of non-pointer");
- let ptr = try!(self.memory.read_ptr(base.ptr));
+ let ptr = self.memory.read_ptr(base.ptr)?;
let extra = match pointee_ty.sty {
ty::TySlice(_) | ty::TyStr => {
let len_ptr = base.ptr.offset(self.memory.pointer_size as isize);
- let len = try!(self.memory.read_usize(len_ptr));
+ let len = self.memory.read_usize(len_ptr)?;
LvalueExtra::Length(len)
}
ty::TyTrait(_) => unimplemented!(),
ty::TySlice(elem_ty) => self.type_size(elem_ty),
_ => panic!("indexing expected an array or slice, got {:?}", base_ty),
};
- let n_ptr = try!(self.eval_operand(operand));
- let n = try!(self.memory.read_usize(n_ptr));
+ let n_ptr = self.eval_operand(operand)?;
+ let n = self.memory.read_usize(n_ptr)?;
base.ptr.offset(n as isize * elem_size as isize)
}
Integral(int) => {
// TODO(tsion): Check int constant type.
let ptr = self.memory.allocate(8);
- try!(self.memory.write_uint(ptr, int.to_u64_unchecked(), 8));
+ self.memory.write_uint(ptr, int.to_u64_unchecked(), 8)?;
Ok(ptr)
}
Str(ref s) => {
let psize = self.memory.pointer_size;
let static_ptr = self.memory.allocate(s.len());
let ptr = self.memory.allocate(psize * 2);
- try!(self.memory.write_bytes(static_ptr, s.as_bytes()));
- try!(self.memory.write_ptr(ptr, static_ptr));
- try!(self.memory.write_usize(ptr.offset(psize as isize), s.len() as u64));
+ self.memory.write_bytes(static_ptr, s.as_bytes())?;
+ self.memory.write_ptr(ptr, static_ptr)?;
+ self.memory.write_usize(ptr.offset(psize as isize), s.len() as u64)?;
Ok(ptr)
}
ByteStr(ref bs) => {
let psize = self.memory.pointer_size;
let static_ptr = self.memory.allocate(bs.len());
let ptr = self.memory.allocate(psize);
- try!(self.memory.write_bytes(static_ptr, bs));
- try!(self.memory.write_ptr(ptr, static_ptr));
+ self.memory.write_bytes(static_ptr, bs)?;
+ self.memory.write_ptr(ptr, static_ptr)?;
Ok(ptr)
}
Bool(b) => {
let ptr = self.memory.allocate(1);
- try!(self.memory.write_bool(ptr, b));
+ self.memory.write_bool(ptr, b)?;
Ok(ptr)
}
Char(_c) => unimplemented!(),
fn move_(&mut self, src: Pointer, dest: Pointer, ty: ty::Ty<'tcx>) -> EvalResult<()> {
let size = self.type_size(ty);
- try!(self.memory.copy(src, dest, size));
+ self.memory.copy(src, dest, size)?;
if self.type_needs_drop(ty) {
- try!(self.memory.drop_fill(src, size));
+ self.memory.drop_fill(src, size)?;
}
Ok(())
}
pub fn read_primval(&mut self, ptr: Pointer, ty: ty::Ty<'tcx>) -> EvalResult<PrimVal> {
use syntax::ast::{IntTy, UintTy};
let val = match ty.sty {
- ty::TyBool => PrimVal::Bool(try!(self.memory.read_bool(ptr))),
- ty::TyInt(IntTy::I8) => PrimVal::I8(try!(self.memory.read_int(ptr, 1)) as i8),
- ty::TyInt(IntTy::I16) => PrimVal::I16(try!(self.memory.read_int(ptr, 2)) as i16),
- ty::TyInt(IntTy::I32) => PrimVal::I32(try!(self.memory.read_int(ptr, 4)) as i32),
- ty::TyInt(IntTy::I64) => PrimVal::I64(try!(self.memory.read_int(ptr, 8)) as i64),
- ty::TyUint(UintTy::U8) => PrimVal::U8(try!(self.memory.read_uint(ptr, 1)) as u8),
- ty::TyUint(UintTy::U16) => PrimVal::U16(try!(self.memory.read_uint(ptr, 2)) as u16),
- ty::TyUint(UintTy::U32) => PrimVal::U32(try!(self.memory.read_uint(ptr, 4)) as u32),
- ty::TyUint(UintTy::U64) => PrimVal::U64(try!(self.memory.read_uint(ptr, 8)) as u64),
+ ty::TyBool => PrimVal::Bool(self.memory.read_bool(ptr)?),
+ ty::TyInt(IntTy::I8) => PrimVal::I8(self.memory.read_int(ptr, 1)? as i8),
+ ty::TyInt(IntTy::I16) => PrimVal::I16(self.memory.read_int(ptr, 2)? as i16),
+ ty::TyInt(IntTy::I32) => PrimVal::I32(self.memory.read_int(ptr, 4)? as i32),
+ ty::TyInt(IntTy::I64) => PrimVal::I64(self.memory.read_int(ptr, 8)? as i64),
+ ty::TyUint(UintTy::U8) => PrimVal::U8(self.memory.read_uint(ptr, 1)? as u8),
+ ty::TyUint(UintTy::U16) => PrimVal::U16(self.memory.read_uint(ptr, 2)? as u16),
+ ty::TyUint(UintTy::U32) => PrimVal::U32(self.memory.read_uint(ptr, 4)? as u32),
+ ty::TyUint(UintTy::U64) => PrimVal::U64(self.memory.read_uint(ptr, 8)? as u64),
// TODO(tsion): Pick the PrimVal dynamically.
- ty::TyInt(IntTy::Is) => PrimVal::I64(try!(self.memory.read_isize(ptr))),
- ty::TyUint(UintTy::Us) => PrimVal::U64(try!(self.memory.read_usize(ptr))),
+ ty::TyInt(IntTy::Is) => PrimVal::I64(self.memory.read_isize(ptr)?),
+ ty::TyUint(UintTy::Us) => PrimVal::U64(self.memory.read_usize(ptr)?),
ty::TyRef(_, ty::TypeAndMut { ty, .. }) |
ty::TyRawPtr(ty::TypeAndMut { ty, .. }) => {
match self.memory.read_ptr(ptr) {
Ok(p) => PrimVal::AbstractPtr(p),
Err(EvalError::ReadBytesAsPointer) => {
- let n = try!(self.memory.read_usize(ptr));
- PrimVal::IntegerPtr(n)
+ PrimVal::IntegerPtr(self.memory.read_usize(ptr)?)
}
Err(e) => return Err(e),
}
panic!()
}
- let alloc = try!(self.get_mut(ptr.alloc_id));
+ let alloc = self.get_mut(ptr.alloc_id)?;
let size = alloc.bytes.len();
if new_size > size {
let amount = new_size - size;
////////////////////////////////////////////////////////////////////////////////
fn get_bytes_unchecked(&self, ptr: Pointer, size: usize) -> EvalResult<&[u8]> {
- let alloc = try!(self.get(ptr.alloc_id));
+ let alloc = self.get(ptr.alloc_id)?;
if ptr.offset + size > alloc.bytes.len() {
return Err(EvalError::PointerOutOfBounds);
}
}
fn get_bytes_unchecked_mut(&mut self, ptr: Pointer, size: usize) -> EvalResult<&mut [u8]> {
- let alloc = try!(self.get_mut(ptr.alloc_id));
+ let alloc = self.get_mut(ptr.alloc_id)?;
if ptr.offset + size > alloc.bytes.len() {
return Err(EvalError::PointerOutOfBounds);
}
}
fn get_bytes(&self, ptr: Pointer, size: usize) -> EvalResult<&[u8]> {
- if try!(self.relocations(ptr, size)).count() != 0 {
+ if self.relocations(ptr, size)?.count() != 0 {
return Err(EvalError::ReadPointerAsBytes);
}
- try!(self.check_defined(ptr, size));
+ self.check_defined(ptr, size)?;
self.get_bytes_unchecked(ptr, size)
}
fn get_bytes_mut(&mut self, ptr: Pointer, size: usize) -> EvalResult<&mut [u8]> {
- try!(self.clear_relocations(ptr, size));
- try!(self.mark_definedness(ptr, size, true));
+ self.clear_relocations(ptr, size)?;
+ self.mark_definedness(ptr, size, true)?;
self.get_bytes_unchecked_mut(ptr, size)
}
////////////////////////////////////////////////////////////////////////////////
pub fn copy(&mut self, src: Pointer, dest: Pointer, size: usize) -> EvalResult<()> {
- try!(self.check_relocation_edges(src, size));
+ self.check_relocation_edges(src, size)?;
- let src_bytes = try!(self.get_bytes_unchecked_mut(src, size)).as_mut_ptr();
- let dest_bytes = try!(self.get_bytes_mut(dest, size)).as_mut_ptr();
+ let src_bytes = self.get_bytes_unchecked_mut(src, size)?.as_mut_ptr();
+ let dest_bytes = self.get_bytes_mut(dest, size)?.as_mut_ptr();
// SAFE: The above indexing would have panicked if there weren't at least `size` bytes
// behind `src` and `dest`. Also, we use the overlapping-safe `ptr::copy` if `src` and
}
}
- try!(self.copy_undef_mask(src, dest, size));
- try!(self.copy_relocations(src, dest, size));
+ self.copy_undef_mask(src, dest, size)?;
+ self.copy_relocations(src, dest, size)?;
Ok(())
}
}
pub fn write_bytes(&mut self, ptr: Pointer, src: &[u8]) -> EvalResult<()> {
- let bytes = try!(self.get_bytes_mut(ptr, src.len()));
+ let bytes = self.get_bytes_mut(ptr, src.len())?;
bytes.clone_from_slice(src);
Ok(())
}
pub fn write_repeat(&mut self, ptr: Pointer, val: u8, count: usize) -> EvalResult<()> {
- let bytes = try!(self.get_bytes_mut(ptr, count));
+ let bytes = self.get_bytes_mut(ptr, count)?;
for b in bytes { *b = val; }
Ok(())
}
pub fn read_ptr(&self, ptr: Pointer) -> EvalResult<Pointer> {
let size = self.pointer_size;
- try!(self.check_defined(ptr, size));
- let offset = try!(self.get_bytes_unchecked(ptr, size))
+ self.check_defined(ptr, size)?;
+ let offset = self.get_bytes_unchecked(ptr, size)?
.read_uint::<NativeEndian>(size).unwrap() as usize;
- let alloc = try!(self.get(ptr.alloc_id));
+ let alloc = self.get(ptr.alloc_id)?;
match alloc.relocations.get(&ptr.offset) {
Some(&alloc_id) => Ok(Pointer { alloc_id: alloc_id, offset: offset }),
None => Err(EvalError::ReadBytesAsPointer),
pub fn write_ptr(&mut self, dest: Pointer, ptr: Pointer) -> EvalResult<()> {
{
let size = self.pointer_size;
- let mut bytes = try!(self.get_bytes_mut(dest, size));
+ let mut bytes = self.get_bytes_mut(dest, size)?;
bytes.write_uint::<NativeEndian>(ptr.offset as u64, size).unwrap();
}
- try!(self.get_mut(dest.alloc_id)).relocations.insert(dest.offset, ptr.alloc_id);
+ self.get_mut(dest.alloc_id)?.relocations.insert(dest.offset, ptr.alloc_id);
Ok(())
}
}
pub fn read_bool(&self, ptr: Pointer) -> EvalResult<bool> {
- let bytes = try!(self.get_bytes(ptr, 1));
+ let bytes = self.get_bytes(ptr, 1)?;
match bytes[0] {
0 => Ok(false),
1 => Ok(true),
{
let start = ptr.offset.saturating_sub(self.pointer_size - 1);
let end = start + size;
- Ok(try!(self.get(ptr.alloc_id)).relocations.range(Included(&start), Excluded(&end)))
+ Ok(self.get(ptr.alloc_id)?.relocations.range(Included(&start), Excluded(&end)))
}
fn clear_relocations(&mut self, ptr: Pointer, size: usize) -> EvalResult<()> {
// Find all relocations overlapping the given range.
- let keys: Vec<_> = try!(self.relocations(ptr, size)).map(|(&k, _)| k).collect();
+ let keys: Vec<_> = self.relocations(ptr, size)?.map(|(&k, _)| k).collect();
if keys.is_empty() { return Ok(()); }
// Find the start and end of the given range and its outermost relocations.
let first = *keys.first().unwrap();
let last = *keys.last().unwrap() + self.pointer_size;
- let alloc = try!(self.get_mut(ptr.alloc_id));
+ let alloc = self.get_mut(ptr.alloc_id)?;
// Mark parts of the outermost relocations as undefined if they partially fall outside the
// given range.
}
fn check_relocation_edges(&self, ptr: Pointer, size: usize) -> EvalResult<()> {
- let overlapping_start = try!(self.relocations(ptr, 0)).count();
- let overlapping_end = try!(self.relocations(ptr.offset(size as isize), 0)).count();
+ let overlapping_start = self.relocations(ptr, 0)?.count();
+ let overlapping_end = self.relocations(ptr.offset(size as isize), 0)?.count();
if overlapping_start + overlapping_end != 0 {
return Err(EvalError::ReadPointerAsBytes);
}
}
fn copy_relocations(&mut self, src: Pointer, dest: Pointer, size: usize) -> EvalResult<()> {
- let relocations: Vec<_> = try!(self.relocations(src, size))
+ let relocations: Vec<_> = self.relocations(src, size)?
.map(|(&offset, &alloc_id)| {
// Update relocation offsets for the new positions in the destination allocation.
(offset + dest.offset - src.offset, alloc_id)
})
.collect();
- try!(self.get_mut(dest.alloc_id)).relocations.extend(relocations);
+ self.get_mut(dest.alloc_id)?.relocations.extend(relocations);
Ok(())
}
// The bits have to be saved locally before writing to dest in case src and dest overlap.
let mut v = Vec::with_capacity(size);
for i in 0..size {
- let defined = try!(self.get(src.alloc_id)).undef_mask.get(src.offset + i);
+ let defined = self.get(src.alloc_id)?.undef_mask.get(src.offset + i);
v.push(defined);
}
for (i, defined) in v.into_iter().enumerate() {
- try!(self.get_mut(dest.alloc_id)).undef_mask.set(dest.offset + i, defined);
+ self.get_mut(dest.alloc_id)?.undef_mask.set(dest.offset + i, defined);
}
Ok(())
}
fn check_defined(&self, ptr: Pointer, size: usize) -> EvalResult<()> {
- let alloc = try!(self.get(ptr.alloc_id));
+ let alloc = self.get(ptr.alloc_id)?;
if !alloc.undef_mask.is_range_defined(ptr.offset, ptr.offset + size) {
return Err(EvalError::ReadUndefBytes);
}
pub fn mark_definedness(&mut self, ptr: Pointer, size: usize, new_state: bool)
-> EvalResult<()>
{
- let mut alloc = try!(self.get_mut(ptr.alloc_id));
+ let mut alloc = self.get_mut(ptr.alloc_id)?;
alloc.undef_mask.set_range(ptr.offset, ptr.offset + size, new_state);
Ok(())
}