@@ -128,7 +128,11 @@ impl<'a, 'tcx> GlobalEvalContext<'a, 'tcx> {
128128 tcx : tcx,
129129 mir_map : mir_map,
130130 mir_cache : RefCell :: new ( DefIdMap ( ) ) ,
131- memory : Memory :: new ( ) ,
131+ memory : Memory :: new ( tcx. sess
132+ . target
133+ . uint_type
134+ . bit_width ( )
135+ . expect ( "Session::target::uint_type was usize" ) /8 ) ,
132136 substs_stack : Vec :: new ( ) ,
133137 name_stack : Vec :: new ( ) ,
134138 }
@@ -392,11 +396,11 @@ impl<'a, 'b, 'mir, 'tcx> FnEvalContext<'a, 'b, 'mir, 'tcx> {
392396 TerminatorTarget :: Call
393397 }
394398
395- abi => panic ! ( "can't handle function with {:?} ABI" , abi) ,
399+ abi => return Err ( EvalError :: Unimplemented ( format ! ( "can't handle function with {:?} ABI" , abi) ) ) ,
396400 }
397401 }
398402
399- _ => panic ! ( "can't handle callee of type {:?}" , func_ty) ,
403+ _ => return Err ( EvalError :: Unimplemented ( format ! ( "can't handle callee of type {:?}" , func_ty) ) ) ,
400404 }
401405 }
402406
@@ -470,7 +474,7 @@ impl<'a, 'b, 'mir, 'tcx> FnEvalContext<'a, 'b, 'mir, 'tcx> {
470474 }
471475
472476 StructWrappedNullablePointer { nndiscr, ref discrfield, .. } => {
473- let offset = self . nonnull_offset ( adt_ty, nndiscr, discrfield) ;
477+ let offset = self . nonnull_offset ( adt_ty, nndiscr, discrfield) ? ;
474478 let nonnull = adt_ptr. offset ( offset. bytes ( ) as isize ) ;
475479 self . read_nonnull_discriminant_value ( nonnull, nndiscr) ?
476480 }
@@ -620,7 +624,7 @@ impl<'a, 'b, 'mir, 'tcx> FnEvalContext<'a, 'b, 'mir, 'tcx> {
620624 self . memory . write_uint ( dest, n * elem_size, dest_size) ?;
621625 }
622626
623- _ => panic ! ( "unimplemented: size_of_val::<{:?}>" , ty) ,
627+ _ => return Err ( EvalError :: Unimplemented ( format ! ( "unimplemented: size_of_val::<{:?}>" , ty) ) ) ,
624628 }
625629 }
626630 }
@@ -631,7 +635,7 @@ impl<'a, 'b, 'mir, 'tcx> FnEvalContext<'a, 'b, 'mir, 'tcx> {
631635 }
632636 "uninit" => self . memory . mark_definedness ( dest, dest_size, false ) ?,
633637
634- name => panic ! ( "can't handle intrinsic: {}" , name) ,
638+ name => return Err ( EvalError :: Unimplemented ( format ! ( "unimplemented intrinsic: {}" , name) ) ) ,
635639 }
636640
637641 // Since we pushed no stack frame, the main loop will act
@@ -693,7 +697,7 @@ impl<'a, 'b, 'mir, 'tcx> FnEvalContext<'a, 'b, 'mir, 'tcx> {
693697 self . memory . write_int ( dest, result, dest_size) ?;
694698 }
695699
696- _ => panic ! ( "can't call C ABI function: {}" , link_name) ,
700+ _ => return Err ( EvalError :: Unimplemented ( format ! ( "can't call C ABI function: {}" , link_name) ) ) ,
697701 }
698702
699703 // Since we pushed no stack frame, the main loop will act
@@ -748,7 +752,7 @@ impl<'a, 'b, 'mir, 'tcx> FnEvalContext<'a, 'b, 'mir, 'tcx> {
748752 let ptr = self . eval_operand ( operand) ?;
749753 let ty = self . operand_ty ( operand) ;
750754 let val = self . read_primval ( ptr, ty) ?;
751- self . memory . write_primval ( dest, primval:: unary_op ( un_op, val) ) ?;
755+ self . memory . write_primval ( dest, primval:: unary_op ( un_op, val) ? ) ?;
752756 }
753757
754758 Aggregate ( ref kind, ref operands) => {
@@ -809,7 +813,7 @@ impl<'a, 'b, 'mir, 'tcx> FnEvalContext<'a, 'b, 'mir, 'tcx> {
809813 try!( self . assign_fields ( dest, offsets, operands) ) ;
810814 } else {
811815 assert_eq ! ( operands. len( ) , 0 ) ;
812- let offset = self . nonnull_offset ( dest_ty, nndiscr, discrfield) ;
816+ let offset = self . nonnull_offset ( dest_ty, nndiscr, discrfield) ? ;
813817 let dest = dest. offset ( offset. bytes ( ) as isize ) ;
814818 try!( self . memory . write_isize ( dest, 0 ) ) ;
815819 }
@@ -834,8 +838,7 @@ impl<'a, 'b, 'mir, 'tcx> FnEvalContext<'a, 'b, 'mir, 'tcx> {
834838 }
835839 }
836840
837- _ => panic ! ( "can't handle destination layout {:?} when assigning {:?}" ,
838- dest_layout, kind) ,
841+ _ => return Err ( EvalError :: Unimplemented ( format ! ( "can't handle destination layout {:?} when assigning {:?}" , dest_layout, kind) ) ) ,
839842 }
840843 }
841844
@@ -904,7 +907,7 @@ impl<'a, 'b, 'mir, 'tcx> FnEvalContext<'a, 'b, 'mir, 'tcx> {
904907 self . memory . write_usize ( len_ptr, length as u64 ) ?;
905908 }
906909
907- _ => panic ! ( "can't handle cast: {:?}" , rvalue) ,
910+ _ => return Err ( EvalError :: Unimplemented ( format ! ( "can't handle cast: {:?}" , rvalue) ) ) ,
908911 }
909912 }
910913
@@ -914,7 +917,7 @@ impl<'a, 'b, 'mir, 'tcx> FnEvalContext<'a, 'b, 'mir, 'tcx> {
914917 self . memory . copy ( src, dest, size) ?;
915918 }
916919
917- _ => panic ! ( "can't handle cast: {:?}" , rvalue) ,
920+ _ => return Err ( EvalError :: Unimplemented ( format ! ( "can't handle cast: {:?}" , rvalue) ) ) ,
918921 }
919922 }
920923
@@ -925,7 +928,7 @@ impl<'a, 'b, 'mir, 'tcx> FnEvalContext<'a, 'b, 'mir, 'tcx> {
925928 Ok ( ( ) )
926929 }
927930
928- fn nonnull_offset ( & self , ty : Ty < ' tcx > , nndiscr : u64 , discrfield : & [ u32 ] ) -> Size {
931+ fn nonnull_offset ( & self , ty : Ty < ' tcx > , nndiscr : u64 , discrfield : & [ u32 ] ) -> EvalResult < Size > {
929932 // Skip the constant 0 at the start meant for LLVM GEP.
930933 let mut path = discrfield. iter ( ) . skip ( 1 ) . map ( |& i| i as usize ) ;
931934
@@ -946,49 +949,49 @@ impl<'a, 'b, 'mir, 'tcx> FnEvalContext<'a, 'b, 'mir, 'tcx> {
946949 self . field_path_offset ( inner_ty, path)
947950 }
948951
949- fn field_path_offset < I : Iterator < Item = usize > > ( & self , mut ty : Ty < ' tcx > , path : I ) -> Size {
952+ fn field_path_offset < I : Iterator < Item = usize > > ( & self , mut ty : Ty < ' tcx > , path : I ) -> EvalResult < Size > {
950953 let mut offset = Size :: from_bytes ( 0 ) ;
951954
952955 // Skip the initial 0 intended for LLVM GEP.
953956 for field_index in path {
954- let field_offset = self . get_field_offset ( ty, field_index) ;
955- ty = self . get_field_ty ( ty, field_index) ;
957+ let field_offset = self . get_field_offset ( ty, field_index) ? ;
958+ ty = self . get_field_ty ( ty, field_index) ? ;
956959 offset = offset. checked_add ( field_offset, & self . tcx . data_layout ) . unwrap ( ) ;
957960 }
958961
959- offset
962+ Ok ( offset)
960963 }
961964
962- fn get_field_ty ( & self , ty : Ty < ' tcx > , field_index : usize ) -> Ty < ' tcx > {
965+ fn get_field_ty ( & self , ty : Ty < ' tcx > , field_index : usize ) -> EvalResult < Ty < ' tcx > > {
963966 match ty. sty {
964967 ty:: TyStruct ( adt_def, substs) => {
965- adt_def. struct_variant ( ) . fields [ field_index] . ty ( self . tcx , substs)
968+ Ok ( adt_def. struct_variant ( ) . fields [ field_index] . ty ( self . tcx , substs) )
966969 }
967970
968971 ty:: TyRef ( _, ty:: TypeAndMut { ty, .. } ) |
969972 ty:: TyRawPtr ( ty:: TypeAndMut { ty, .. } ) |
970973 ty:: TyBox ( ty) => {
971974 assert_eq ! ( field_index, 0 ) ;
972- ty
975+ Ok ( ty )
973976 }
974- _ => panic ! ( "can't handle type: {:?}" , ty) ,
977+ _ => Err ( EvalError :: Unimplemented ( format ! ( "can't handle type: {:?}" , ty) ) ) ,
975978 }
976979 }
977980
978- fn get_field_offset ( & self , ty : Ty < ' tcx > , field_index : usize ) -> Size {
981+ fn get_field_offset ( & self , ty : Ty < ' tcx > , field_index : usize ) -> EvalResult < Size > {
979982 let layout = self . type_layout ( ty) ;
980983
981984 use rustc:: ty:: layout:: Layout :: * ;
982985 match * layout {
983986 Univariant { .. } => {
984987 assert_eq ! ( field_index, 0 ) ;
985- Size :: from_bytes ( 0 )
988+ Ok ( Size :: from_bytes ( 0 ) )
986989 }
987990 FatPointer { .. } => {
988991 let bytes = layout:: FAT_PTR_ADDR * self . memory . pointer_size ;
989- Size :: from_bytes ( bytes as u64 )
992+ Ok ( Size :: from_bytes ( bytes as u64 ) )
990993 }
991- _ => panic ! ( "can't handle type: {:?}, with layout: {:?}" , ty, layout) ,
994+ _ => Err ( EvalError :: Unimplemented ( format ! ( "can't handle type: {:?}, with layout: {:?}" , ty, layout) ) ) ,
992995 }
993996 }
994997
@@ -1197,23 +1200,25 @@ impl<'a, 'b, 'mir, 'tcx> FnEvalContext<'a, 'b, 'mir, 'tcx> {
11971200
11981201 pub fn read_primval ( & mut self , ptr : Pointer , ty : Ty < ' tcx > ) -> EvalResult < PrimVal > {
11991202 use syntax:: ast:: { IntTy , UintTy } ;
1200- let val = match ty. sty {
1201- ty:: TyBool => PrimVal :: Bool ( self . memory . read_bool ( ptr) ?) ,
1202- ty:: TyInt ( IntTy :: I8 ) => PrimVal :: I8 ( self . memory . read_int ( ptr, 1 ) ? as i8 ) ,
1203- ty:: TyInt ( IntTy :: I16 ) => PrimVal :: I16 ( self . memory . read_int ( ptr, 2 ) ? as i16 ) ,
1204- ty:: TyInt ( IntTy :: I32 ) => PrimVal :: I32 ( self . memory . read_int ( ptr, 4 ) ? as i32 ) ,
1205- ty:: TyInt ( IntTy :: I64 ) => PrimVal :: I64 ( self . memory . read_int ( ptr, 8 ) ? as i64 ) ,
1206- ty:: TyUint ( UintTy :: U8 ) => PrimVal :: U8 ( self . memory . read_uint ( ptr, 1 ) ? as u8 ) ,
1207- ty:: TyUint ( UintTy :: U16 ) => PrimVal :: U16 ( self . memory . read_uint ( ptr, 2 ) ? as u16 ) ,
1208- ty:: TyUint ( UintTy :: U32 ) => PrimVal :: U32 ( self . memory . read_uint ( ptr, 4 ) ? as u32 ) ,
1209- ty:: TyUint ( UintTy :: U64 ) => PrimVal :: U64 ( self . memory . read_uint ( ptr, 8 ) ? as u64 ) ,
1210-
1211- // TODO(solson): Pick the PrimVal dynamically.
1212- ty:: TyInt ( IntTy :: Is ) => PrimVal :: I64 ( self . memory . read_isize ( ptr) ?) ,
1213- ty:: TyUint ( UintTy :: Us ) => PrimVal :: U64 ( self . memory . read_usize ( ptr) ?) ,
1214-
1215- ty:: TyRef ( _, ty:: TypeAndMut { ty, .. } ) |
1216- ty:: TyRawPtr ( ty:: TypeAndMut { ty, .. } ) => {
1203+ let val = match ( self . memory . pointer_size , & ty. sty ) {
1204+ ( _, & ty:: TyBool ) => PrimVal :: Bool ( self . memory . read_bool ( ptr) ?) ,
1205+ ( _, & ty:: TyInt ( IntTy :: I8 ) ) => PrimVal :: I8 ( self . memory . read_int ( ptr, 1 ) ? as i8 ) ,
1206+ ( 2 , & ty:: TyInt ( IntTy :: Is ) ) |
1207+ ( _, & ty:: TyInt ( IntTy :: I16 ) ) => PrimVal :: I16 ( self . memory . read_int ( ptr, 2 ) ? as i16 ) ,
1208+ ( 4 , & ty:: TyInt ( IntTy :: Is ) ) |
1209+ ( _, & ty:: TyInt ( IntTy :: I32 ) ) => PrimVal :: I32 ( self . memory . read_int ( ptr, 4 ) ? as i32 ) ,
1210+ ( 8 , & ty:: TyInt ( IntTy :: Is ) ) |
1211+ ( _, & ty:: TyInt ( IntTy :: I64 ) ) => PrimVal :: I64 ( self . memory . read_int ( ptr, 8 ) ? as i64 ) ,
1212+ ( _, & ty:: TyUint ( UintTy :: U8 ) ) => PrimVal :: U8 ( self . memory . read_uint ( ptr, 1 ) ? as u8 ) ,
1213+ ( 2 , & ty:: TyUint ( UintTy :: Us ) ) |
1214+ ( _, & ty:: TyUint ( UintTy :: U16 ) ) => PrimVal :: U16 ( self . memory . read_uint ( ptr, 2 ) ? as u16 ) ,
1215+ ( 4 , & ty:: TyUint ( UintTy :: Us ) ) |
1216+ ( _, & ty:: TyUint ( UintTy :: U32 ) ) => PrimVal :: U32 ( self . memory . read_uint ( ptr, 4 ) ? as u32 ) ,
1217+ ( 8 , & ty:: TyUint ( UintTy :: Us ) ) |
1218+ ( _, & ty:: TyUint ( UintTy :: U64 ) ) => PrimVal :: U64 ( self . memory . read_uint ( ptr, 8 ) ? as u64 ) ,
1219+
1220+ ( _, & ty:: TyRef ( _, ty:: TypeAndMut { ty, .. } ) ) |
1221+ ( _, & ty:: TyRawPtr ( ty:: TypeAndMut { ty, .. } ) ) => {
12171222 if self . type_is_sized ( ty) {
12181223 match self . memory . read_ptr ( ptr) {
12191224 Ok ( p) => PrimVal :: AbstractPtr ( p) ,
@@ -1223,7 +1228,7 @@ impl<'a, 'b, 'mir, 'tcx> FnEvalContext<'a, 'b, 'mir, 'tcx> {
12231228 Err ( e) => return Err ( e) ,
12241229 }
12251230 } else {
1226- panic ! ( "unimplemented: primitive read of fat pointer type: {:?}" , ty) ;
1231+ return Err ( EvalError :: Unimplemented ( format ! ( "unimplemented: primitive read of fat pointer type: {:?}" , ty) ) ) ;
12271232 }
12281233 }
12291234
0 commit comments