]> git.lizzy.rs Git - rust.git/commitdiff
replace `panic!`s with `Result`
authorOliver Schneider <git-spam-no-reply9815368754983@oli-obk.de>
Mon, 30 May 2016 13:27:52 +0000 (15:27 +0200)
committerOliver Schneider <git-spam-no-reply9815368754983@oli-obk.de>
Wed, 1 Jun 2016 09:10:43 +0000 (11:10 +0200)
src/error.rs
src/interpreter.rs
src/memory.rs
src/primval.rs

index 65dd187fa0b600fdf5ed5fbda8d7051b52ae61f3..ec75ab44526953d5fec00e4b7646e849d3ac40fb 100644 (file)
@@ -1,5 +1,6 @@
 use std::error::Error;
 use std::fmt;
+use rustc::mir::repr as mir;
 
 #[derive(Clone, Debug)]
 pub enum EvalError {
@@ -11,6 +12,8 @@ pub enum EvalError {
     ReadBytesAsPointer,
     InvalidPointerMath,
     ReadUndefBytes,
+    InvalidBoolOp(mir::BinOp),
+    Unimplemented(String),
 }
 
 pub type EvalResult<T> = Result<T, EvalError>;
@@ -34,6 +37,9 @@ fn description(&self) -> &str {
                 "attempted to do math or a comparison on pointers into different allocations",
             EvalError::ReadUndefBytes =>
                 "attempted to read undefined bytes",
+            EvalError::InvalidBoolOp(_) =>
+                "invalid boolean operation",
+            EvalError::Unimplemented(ref msg) => msg,
         }
     }
 
index 8e8565b50c55c302a43119438cd214be0124e321..8734427f07f579246823b20de9a4fba18dcc41d5 100644 (file)
@@ -392,11 +392,11 @@ fn eval_terminator(&mut self, terminator: &mir::Terminator<'tcx>)
                                 TerminatorTarget::Call
                             }
 
-                            abi => panic!("can't handle function with {:?} ABI", abi),
+                            abi => return Err(EvalError::Unimplemented(format!("can't handle function with {:?} ABI", abi))),
                         }
                     }
 
-                    _ => panic!("can't handle callee of type {:?}", func_ty),
+                    _ => return Err(EvalError::Unimplemented(format!("can't handle callee of type {:?}", func_ty))),
                 }
             }
 
@@ -470,7 +470,7 @@ fn read_discriminant_value(&self, adt_ptr: Pointer, adt_ty: Ty<'tcx>) -> EvalRes
             }
 
             StructWrappedNullablePointer { nndiscr, ref discrfield, .. } => {
-                let offset = self.nonnull_offset(adt_ty, nndiscr, discrfield);
+                let offset = self.nonnull_offset(adt_ty, nndiscr, discrfield)?;
                 let nonnull = adt_ptr.offset(offset.bytes() as isize);
                 self.read_nonnull_discriminant_value(nonnull, nndiscr)?
             }
@@ -620,7 +620,7 @@ fn call_intrinsic(
                             self.memory.write_uint(dest, n * elem_size, dest_size)?;
                         }
 
-                        _ => panic!("unimplemented: size_of_val::<{:?}>", ty),
+                        _ => return Err(EvalError::Unimplemented(format!("unimplemented: size_of_val::<{:?}>", ty))),
                     }
                 }
             }
@@ -631,7 +631,7 @@ fn call_intrinsic(
             }
             "uninit" => self.memory.mark_definedness(dest, dest_size, false)?,
 
-            name => panic!("can't handle intrinsic: {}", name),
+            name => return Err(EvalError::Unimplemented(format!("unimplemented intrinsic: {}", name))),
         }
 
         // Since we pushed no stack frame, the main loop will act
@@ -693,7 +693,7 @@ fn call_c_abi(
                 self.memory.write_int(dest, result, dest_size)?;
             }
 
-            _ => panic!("can't call C ABI function: {}", link_name),
+            _ => return Err(EvalError::Unimplemented(format!("can't call C ABI function: {}", link_name))),
         }
 
         // Since we pushed no stack frame, the main loop will act
@@ -748,7 +748,7 @@ fn eval_assignment(&mut self, lvalue: &mir::Lvalue<'tcx>, rvalue: &mir::Rvalue<'
                 let ptr = self.eval_operand(operand)?;
                 let ty = self.operand_ty(operand);
                 let val = self.read_primval(ptr, ty)?;
-                self.memory.write_primval(dest, primval::unary_op(un_op, val))?;
+                self.memory.write_primval(dest, primval::unary_op(un_op, val)?)?;
             }
 
             Aggregate(ref kind, ref operands) => {
@@ -809,7 +809,7 @@ fn eval_assignment(&mut self, lvalue: &mir::Lvalue<'tcx>, rvalue: &mir::Rvalue<'
                                 try!(self.assign_fields(dest, offsets, operands));
                             } else {
                                 assert_eq!(operands.len(), 0);
-                                let offset = self.nonnull_offset(dest_ty, nndiscr, discrfield);
+                                let offset = self.nonnull_offset(dest_ty, nndiscr, discrfield)?;
                                 let dest = dest.offset(offset.bytes() as isize);
                                 try!(self.memory.write_isize(dest, 0));
                             }
@@ -834,8 +834,7 @@ fn eval_assignment(&mut self, lvalue: &mir::Lvalue<'tcx>, rvalue: &mir::Rvalue<'
                         }
                     }
 
-                    _ => panic!("can't handle destination layout {:?} when assigning {:?}",
-                                dest_layout, kind),
+                    _ => return Err(EvalError::Unimplemented(format!("can't handle destination layout {:?} when assigning {:?}", dest_layout, kind))),
                 }
             }
 
@@ -904,7 +903,7 @@ fn eval_assignment(&mut self, lvalue: &mir::Lvalue<'tcx>, rvalue: &mir::Rvalue<'
                                 self.memory.write_usize(len_ptr, length as u64)?;
                             }
 
-                            _ => panic!("can't handle cast: {:?}", rvalue),
+                            _ => return Err(EvalError::Unimplemented(format!("can't handle cast: {:?}", rvalue))),
                         }
                     }
 
@@ -914,7 +913,7 @@ fn eval_assignment(&mut self, lvalue: &mir::Lvalue<'tcx>, rvalue: &mir::Rvalue<'
                         self.memory.copy(src, dest, size)?;
                     }
 
-                    _ => panic!("can't handle cast: {:?}", rvalue),
+                    _ => return Err(EvalError::Unimplemented(format!("can't handle cast: {:?}", rvalue))),
                 }
             }
 
@@ -925,7 +924,7 @@ fn eval_assignment(&mut self, lvalue: &mir::Lvalue<'tcx>, rvalue: &mir::Rvalue<'
         Ok(())
     }
 
-    fn nonnull_offset(&self, ty: Ty<'tcx>, nndiscr: u64, discrfield: &[u32]) -> Size {
+    fn nonnull_offset(&self, ty: Ty<'tcx>, nndiscr: u64, discrfield: &[u32]) -> EvalResult<Size> {
         // Skip the constant 0 at the start meant for LLVM GEP.
         let mut path = discrfield.iter().skip(1).map(|&i| i as usize);
 
@@ -946,49 +945,49 @@ fn nonnull_offset(&self, ty: Ty<'tcx>, nndiscr: u64, discrfield: &[u32]) -> Size
         self.field_path_offset(inner_ty, path)
     }
 
-    fn field_path_offset<I: Iterator<Item = usize>>(&self, mut ty: Ty<'tcx>, path: I) -> Size {
+    fn field_path_offset<I: Iterator<Item = usize>>(&self, mut ty: Ty<'tcx>, path: I) -> EvalResult<Size> {
         let mut offset = Size::from_bytes(0);
 
         // Skip the initial 0 intended for LLVM GEP.
         for field_index in path {
-            let field_offset = self.get_field_offset(ty, field_index);
-            ty = self.get_field_ty(ty, field_index);
+            let field_offset = self.get_field_offset(ty, field_index)?;
+            ty = self.get_field_ty(ty, field_index)?;
             offset = offset.checked_add(field_offset, &self.tcx.data_layout).unwrap();
         }
 
-        offset
+        Ok(offset)
     }
 
-    fn get_field_ty(&self, ty: Ty<'tcx>, field_index: usize) -> Ty<'tcx> {
+    fn get_field_ty(&self, ty: Ty<'tcx>, field_index: usize) -> EvalResult<Ty<'tcx>> {
         match ty.sty {
             ty::TyStruct(adt_def, substs) => {
-                adt_def.struct_variant().fields[field_index].ty(self.tcx, substs)
+                Ok(adt_def.struct_variant().fields[field_index].ty(self.tcx, substs))
             }
 
             ty::TyRef(_, ty::TypeAndMut { ty, .. }) |
             ty::TyRawPtr(ty::TypeAndMut { ty, .. }) |
             ty::TyBox(ty) => {
                 assert_eq!(field_index, 0);
-                ty
+                Ok(ty)
             }
-            _ => panic!("can't handle type: {:?}", ty),
+            _ => Err(EvalError::Unimplemented(format!("can't handle type: {:?}", ty))),
         }
     }
 
-    fn get_field_offset(&self, ty: Ty<'tcx>, field_index: usize) -> Size {
+    fn get_field_offset(&self, ty: Ty<'tcx>, field_index: usize) -> EvalResult<Size> {
         let layout = self.type_layout(ty);
 
         use rustc::ty::layout::Layout::*;
         match *layout {
             Univariant { .. } => {
                 assert_eq!(field_index, 0);
-                Size::from_bytes(0)
+                Ok(Size::from_bytes(0))
             }
             FatPointer { .. } => {
                 let bytes = layout::FAT_PTR_ADDR * self.memory.pointer_size;
-                Size::from_bytes(bytes as u64)
+                Ok(Size::from_bytes(bytes as u64))
             }
-            _ => panic!("can't handle type: {:?}, with layout: {:?}", ty, layout),
+            _ => Err(EvalError::Unimplemented(format!("can't handle type: {:?}, with layout: {:?}", ty, layout))),
         }
     }
 
@@ -1223,7 +1222,7 @@ pub fn read_primval(&mut self, ptr: Pointer, ty: Ty<'tcx>) -> EvalResult<PrimVal
                         Err(e) => return Err(e),
                     }
                 } else {
-                    panic!("unimplemented: primitive read of fat pointer type: {:?}", ty);
+                    return Err(EvalError::Unimplemented(format!("unimplemented: primitive read of fat pointer type: {:?}", ty)));
                 }
             }
 
index a42fd54669b635a01d8ad7e02e1b64d4fd24ec30..d69e07ae2a2b85dc5e5c599b1adae688857f9c40 100644 (file)
@@ -80,7 +80,7 @@ pub fn allocate(&mut self, size: usize) -> Pointer {
     pub fn reallocate(&mut self, ptr: Pointer, new_size: usize) -> EvalResult<()> {
         if ptr.offset != 0 {
             // TODO(solson): Report error about non-__rust_allocate'd pointer.
-            panic!()
+            return Err(EvalError::Unimplemented(format!("bad pointer offset: {}", ptr.offset)));
         }
 
         let alloc = self.get_mut(ptr.alloc_id)?;
@@ -90,7 +90,7 @@ pub fn reallocate(&mut self, ptr: Pointer, new_size: usize) -> EvalResult<()> {
             alloc.bytes.extend(iter::repeat(0).take(amount));
             alloc.undef_mask.grow(amount, false);
         } else if size > new_size {
-            unimplemented!()
+            return Err(EvalError::Unimplemented(format!("unimplemented allocation relocation")));
             // alloc.bytes.truncate(new_size);
             // alloc.undef_mask.len = new_size;
             // TODO: potentially remove relocations
@@ -103,7 +103,7 @@ pub fn reallocate(&mut self, ptr: Pointer, new_size: usize) -> EvalResult<()> {
     pub fn deallocate(&mut self, ptr: Pointer) -> EvalResult<()> {
         if ptr.offset != 0 {
             // TODO(solson): Report error about non-__rust_allocate'd pointer.
-            panic!()
+            return Err(EvalError::Unimplemented(format!("bad pointer offset: {}", ptr.offset)));
         }
 
         if self.alloc_map.remove(&ptr.alloc_id).is_none() {
index 19faadc962e162bf15fb05b8fcaf6baba5ce34d6..0b1658739d9d6a4832abc7cbdac68af8fc546b07 100644 (file)
@@ -74,8 +74,7 @@ fn unrelated_ptr_ops(bin_op: mir::BinOp) -> EvalResult<PrimVal> {
                 BitOr => l | r,
                 BitXor => l ^ r,
                 BitAnd => l & r,
-                Add | Sub | Mul | Div | Rem | Shl | Shr =>
-                    panic!("invalid binary operation on booleans: {:?}", bin_op),
+                Add | Sub | Mul | Div | Rem | Shl | Shr => return Err(EvalError::InvalidBoolOp(bin_op)),
             })
         }
 
@@ -99,33 +98,33 @@ fn unrelated_ptr_ops(bin_op: mir::BinOp) -> EvalResult<PrimVal> {
                 Le => Bool(l <= r),
                 Gt => Bool(l > r),
                 Ge => Bool(l >= r),
-                _ => unimplemented!(),
+                _ => return Err(EvalError::Unimplemented(format!("unimplemented ptr op: {:?}", bin_op))),
             }
         }
 
-        _ => unimplemented!(),
+        (l, r) => return Err(EvalError::Unimplemented(format!("unimplemented binary op: {:?}, {:?}, {:?}", l, r, bin_op))),
     };
 
     Ok(val)
 }
 
-pub fn unary_op(un_op: mir::UnOp, val: PrimVal) -> PrimVal {
+pub fn unary_op(un_op: mir::UnOp, val: PrimVal) -> EvalResult<PrimVal> {
     use rustc::mir::repr::UnOp::*;
     use self::PrimVal::*;
     match (un_op, val) {
-        (Not, Bool(b)) => Bool(!b),
-        (Not, I8(n))  => I8(!n),
-        (Neg, I8(n))  => I8(-n),
-        (Not, I16(n)) => I16(!n),
-        (Neg, I16(n)) => I16(-n),
-        (Not, I32(n)) => I32(!n),
-        (Neg, I32(n)) => I32(-n),
-        (Not, I64(n)) => I64(!n),
-        (Neg, I64(n)) => I64(-n),
-        (Not, U8(n))  => U8(!n),
-        (Not, U16(n)) => U16(!n),
-        (Not, U32(n)) => U32(!n),
-        (Not, U64(n)) => U64(!n),
-        _ => unimplemented!(),
+        (Not, Bool(b)) => Ok(Bool(!b)),
+        (Not, I8(n))  => Ok(I8(!n)),
+        (Neg, I8(n))  => Ok(I8(-n)),
+        (Not, I16(n)) => Ok(I16(!n)),
+        (Neg, I16(n)) => Ok(I16(-n)),
+        (Not, I32(n)) => Ok(I32(!n)),
+        (Neg, I32(n)) => Ok(I32(-n)),
+        (Not, I64(n)) => Ok(I64(!n)),
+        (Neg, I64(n)) => Ok(I64(-n)),
+        (Not, U8(n))  => Ok(U8(!n)),
+        (Not, U16(n)) => Ok(U16(!n)),
+        (Not, U32(n)) => Ok(U32(!n)),
+        (Not, U64(n)) => Ok(U64(!n)),
+        _ => Err(EvalError::Unimplemented(format!("unimplemented unary op: {:?}, {:?}", un_op, val))),
     }
 }