@@ -128,7 +128,11 @@ impl<'a, 'tcx> GlobalEvalContext<'a, 'tcx> {
128
128
tcx : tcx,
129
129
mir_map : mir_map,
130
130
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 ) ,
132
136
substs_stack : Vec :: new ( ) ,
133
137
name_stack : Vec :: new ( ) ,
134
138
}
@@ -392,11 +396,11 @@ impl<'a, 'b, 'mir, 'tcx> FnEvalContext<'a, 'b, 'mir, 'tcx> {
392
396
TerminatorTarget :: Call
393
397
}
394
398
395
- abi => panic ! ( "can't handle function with {:?} ABI" , abi) ,
399
+ abi => return Err ( EvalError :: Unimplemented ( format ! ( "can't handle function with {:?} ABI" , abi) ) ) ,
396
400
}
397
401
}
398
402
399
- _ => panic ! ( "can't handle callee of type {:?}" , func_ty) ,
403
+ _ => return Err ( EvalError :: Unimplemented ( format ! ( "can't handle callee of type {:?}" , func_ty) ) ) ,
400
404
}
401
405
}
402
406
@@ -470,7 +474,7 @@ impl<'a, 'b, 'mir, 'tcx> FnEvalContext<'a, 'b, 'mir, 'tcx> {
470
474
}
471
475
472
476
StructWrappedNullablePointer { nndiscr, ref discrfield, .. } => {
473
- let offset = self . nonnull_offset ( adt_ty, nndiscr, discrfield) ;
477
+ let offset = self . nonnull_offset ( adt_ty, nndiscr, discrfield) ? ;
474
478
let nonnull = adt_ptr. offset ( offset. bytes ( ) as isize ) ;
475
479
self . read_nonnull_discriminant_value ( nonnull, nndiscr) ?
476
480
}
@@ -620,7 +624,7 @@ impl<'a, 'b, 'mir, 'tcx> FnEvalContext<'a, 'b, 'mir, 'tcx> {
620
624
self . memory . write_uint ( dest, n * elem_size, dest_size) ?;
621
625
}
622
626
623
- _ => panic ! ( "unimplemented: size_of_val::<{:?}>" , ty) ,
627
+ _ => return Err ( EvalError :: Unimplemented ( format ! ( "unimplemented: size_of_val::<{:?}>" , ty) ) ) ,
624
628
}
625
629
}
626
630
}
@@ -631,7 +635,7 @@ impl<'a, 'b, 'mir, 'tcx> FnEvalContext<'a, 'b, 'mir, 'tcx> {
631
635
}
632
636
"uninit" => self . memory . mark_definedness ( dest, dest_size, false ) ?,
633
637
634
- name => panic ! ( "can't handle intrinsic: {}" , name) ,
638
+ name => return Err ( EvalError :: Unimplemented ( format ! ( "unimplemented intrinsic: {}" , name) ) ) ,
635
639
}
636
640
637
641
// 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> {
693
697
self . memory . write_int ( dest, result, dest_size) ?;
694
698
}
695
699
696
- _ => panic ! ( "can't call C ABI function: {}" , link_name) ,
700
+ _ => return Err ( EvalError :: Unimplemented ( format ! ( "can't call C ABI function: {}" , link_name) ) ) ,
697
701
}
698
702
699
703
// 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> {
748
752
let ptr = self . eval_operand ( operand) ?;
749
753
let ty = self . operand_ty ( operand) ;
750
754
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) ? ) ?;
752
756
}
753
757
754
758
Aggregate ( ref kind, ref operands) => {
@@ -809,7 +813,7 @@ impl<'a, 'b, 'mir, 'tcx> FnEvalContext<'a, 'b, 'mir, 'tcx> {
809
813
try!( self . assign_fields ( dest, offsets, operands) ) ;
810
814
} else {
811
815
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) ? ;
813
817
let dest = dest. offset ( offset. bytes ( ) as isize ) ;
814
818
try!( self . memory . write_isize ( dest, 0 ) ) ;
815
819
}
@@ -834,8 +838,7 @@ impl<'a, 'b, 'mir, 'tcx> FnEvalContext<'a, 'b, 'mir, 'tcx> {
834
838
}
835
839
}
836
840
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) ) ) ,
839
842
}
840
843
}
841
844
@@ -904,7 +907,7 @@ impl<'a, 'b, 'mir, 'tcx> FnEvalContext<'a, 'b, 'mir, 'tcx> {
904
907
self . memory . write_usize ( len_ptr, length as u64 ) ?;
905
908
}
906
909
907
- _ => panic ! ( "can't handle cast: {:?}" , rvalue) ,
910
+ _ => return Err ( EvalError :: Unimplemented ( format ! ( "can't handle cast: {:?}" , rvalue) ) ) ,
908
911
}
909
912
}
910
913
@@ -914,7 +917,7 @@ impl<'a, 'b, 'mir, 'tcx> FnEvalContext<'a, 'b, 'mir, 'tcx> {
914
917
self . memory . copy ( src, dest, size) ?;
915
918
}
916
919
917
- _ => panic ! ( "can't handle cast: {:?}" , rvalue) ,
920
+ _ => return Err ( EvalError :: Unimplemented ( format ! ( "can't handle cast: {:?}" , rvalue) ) ) ,
918
921
}
919
922
}
920
923
@@ -925,7 +928,7 @@ impl<'a, 'b, 'mir, 'tcx> FnEvalContext<'a, 'b, 'mir, 'tcx> {
925
928
Ok ( ( ) )
926
929
}
927
930
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 > {
929
932
// Skip the constant 0 at the start meant for LLVM GEP.
930
933
let mut path = discrfield. iter ( ) . skip ( 1 ) . map ( |& i| i as usize ) ;
931
934
@@ -946,49 +949,49 @@ impl<'a, 'b, 'mir, 'tcx> FnEvalContext<'a, 'b, 'mir, 'tcx> {
946
949
self . field_path_offset ( inner_ty, path)
947
950
}
948
951
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 > {
950
953
let mut offset = Size :: from_bytes ( 0 ) ;
951
954
952
955
// Skip the initial 0 intended for LLVM GEP.
953
956
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) ? ;
956
959
offset = offset. checked_add ( field_offset, & self . tcx . data_layout ) . unwrap ( ) ;
957
960
}
958
961
959
- offset
962
+ Ok ( offset)
960
963
}
961
964
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 > > {
963
966
match ty. sty {
964
967
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) )
966
969
}
967
970
968
971
ty:: TyRef ( _, ty:: TypeAndMut { ty, .. } ) |
969
972
ty:: TyRawPtr ( ty:: TypeAndMut { ty, .. } ) |
970
973
ty:: TyBox ( ty) => {
971
974
assert_eq ! ( field_index, 0 ) ;
972
- ty
975
+ Ok ( ty )
973
976
}
974
- _ => panic ! ( "can't handle type: {:?}" , ty) ,
977
+ _ => Err ( EvalError :: Unimplemented ( format ! ( "can't handle type: {:?}" , ty) ) ) ,
975
978
}
976
979
}
977
980
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 > {
979
982
let layout = self . type_layout ( ty) ;
980
983
981
984
use rustc:: ty:: layout:: Layout :: * ;
982
985
match * layout {
983
986
Univariant { .. } => {
984
987
assert_eq ! ( field_index, 0 ) ;
985
- Size :: from_bytes ( 0 )
988
+ Ok ( Size :: from_bytes ( 0 ) )
986
989
}
987
990
FatPointer { .. } => {
988
991
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 ) )
990
993
}
991
- _ => panic ! ( "can't handle type: {:?}, with layout: {:?}" , ty, layout) ,
994
+ _ => Err ( EvalError :: Unimplemented ( format ! ( "can't handle type: {:?}, with layout: {:?}" , ty, layout) ) ) ,
992
995
}
993
996
}
994
997
@@ -1197,23 +1200,25 @@ impl<'a, 'b, 'mir, 'tcx> FnEvalContext<'a, 'b, 'mir, 'tcx> {
1197
1200
1198
1201
pub fn read_primval ( & mut self , ptr : Pointer , ty : Ty < ' tcx > ) -> EvalResult < PrimVal > {
1199
1202
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, .. } ) ) => {
1217
1222
if self . type_is_sized ( ty) {
1218
1223
match self . memory . read_ptr ( ptr) {
1219
1224
Ok ( p) => PrimVal :: AbstractPtr ( p) ,
@@ -1223,7 +1228,7 @@ impl<'a, 'b, 'mir, 'tcx> FnEvalContext<'a, 'b, 'mir, 'tcx> {
1223
1228
Err ( e) => return Err ( e) ,
1224
1229
}
1225
1230
} 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) ) ) ;
1227
1232
}
1228
1233
}
1229
1234
0 commit comments