@@ -18,7 +18,7 @@ use crate::*;
1818impl < ' mir , ' tcx > EvalContextExt < ' mir , ' tcx > for crate :: MiriEvalContext < ' mir , ' tcx > { }
1919
2020/// Gets an instance for a path.
21- fn resolve_did < ' mir , ' tcx > ( tcx : TyCtxt < ' tcx > , path : & [ & str ] ) -> InterpResult < ' tcx , DefId > {
21+ fn try_resolve_did < ' mir , ' tcx > ( tcx : TyCtxt < ' tcx > , path : & [ & str ] ) -> Option < DefId > {
2222 tcx. crates ( )
2323 . iter ( )
2424 . find ( |& & krate| tcx. original_crate_name ( krate) . as_str ( ) == path[ 0 ] )
@@ -41,19 +41,47 @@ fn resolve_did<'mir, 'tcx>(tcx: TyCtxt<'tcx>, path: &[&str]) -> InterpResult<'tc
4141 }
4242 None
4343 } )
44- . ok_or_else ( || {
45- let path = path. iter ( ) . map ( |& s| s. to_owned ( ) ) . collect ( ) ;
46- err_unsup ! ( PathNotFound ( path) ) . into ( )
47- } )
4844}
4945
5046pub trait EvalContextExt < ' mir , ' tcx : ' mir > : crate :: MiriEvalContextExt < ' mir , ' tcx > {
5147 /// Gets an instance for a path.
52- fn resolve_path ( & self , path : & [ & str ] ) -> InterpResult < ' tcx , ty:: Instance < ' tcx > > {
53- Ok ( ty:: Instance :: mono (
54- self . eval_context_ref ( ) . tcx . tcx ,
55- resolve_did ( self . eval_context_ref ( ) . tcx . tcx , path) ?,
56- ) )
48+ fn resolve_path ( & self , path : & [ & str ] ) -> ty:: Instance < ' tcx > {
49+ let did = try_resolve_did ( self . eval_context_ref ( ) . tcx . tcx , path)
50+ . unwrap_or_else ( || panic ! ( "failed to find required Rust item: {:?}" , path) ) ;
51+ ty:: Instance :: mono ( self . eval_context_ref ( ) . tcx . tcx , did)
52+ }
53+
54+ /// Evaluates the scalar at the specified path. Returns Some(val)
55+ /// if the path could be resolved, and None otherwise
56+ fn eval_path_scalar (
57+ & mut self ,
58+ path : & [ & str ] ,
59+ ) -> InterpResult < ' tcx , ScalarMaybeUndef < Tag > > {
60+ let this = self . eval_context_mut ( ) ;
61+ let instance = this. resolve_path ( path) ;
62+ let cid = GlobalId { instance, promoted : None } ;
63+ let const_val = this. const_eval_raw ( cid) ?;
64+ let const_val = this. read_scalar ( const_val. into ( ) ) ?;
65+ return Ok ( const_val) ;
66+ }
67+
68+ /// Helper function to get a `libc` constant as a `Scalar`.
69+ fn eval_libc ( & mut self , name : & str ) -> InterpResult < ' tcx , Scalar < Tag > > {
70+ self . eval_context_mut ( )
71+ . eval_path_scalar ( & [ "libc" , name] ) ?
72+ . not_undef ( )
73+ }
74+
75+ /// Helper function to get a `libc` constant as an `i32`.
76+ fn eval_libc_i32 ( & mut self , name : & str ) -> InterpResult < ' tcx , i32 > {
77+ self . eval_libc ( name) ?. to_i32 ( )
78+ }
79+
80+ /// Helper function to get the `TyLayout` of a `libc` type
81+ fn libc_ty_layout ( & mut self , name : & str ) -> InterpResult < ' tcx , TyLayout < ' tcx > > {
82+ let this = self . eval_context_mut ( ) ;
83+ let ty = this. resolve_path ( & [ "libc" , name] ) . monomorphic_ty ( * this. tcx ) ;
84+ this. layout_of ( ty)
5785 }
5886
5987 /// Write a 0 of the appropriate size to `dest`.
@@ -98,7 +126,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
98126 if this. machine . communicate {
99127 // Fill the buffer using the host's rng.
100128 getrandom:: getrandom ( & mut data)
101- . map_err ( |err| err_unsup_format ! ( "getrandom failed: {}" , err) ) ?;
129+ . map_err ( |err| err_unsup_format ! ( "host getrandom failed: {}" , err) ) ?;
102130 } else {
103131 let rng = this. memory . extra . rng . get_mut ( ) ;
104132 rng. fill_bytes ( & mut data) ;
@@ -313,26 +341,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
313341 }
314342 }
315343
316- /// Helper function to get a `libc` constant as a `Scalar`.
317- fn eval_libc ( & mut self , name : & str ) -> InterpResult < ' tcx , Scalar < Tag > > {
318- self . eval_context_mut ( )
319- . eval_path_scalar ( & [ "libc" , name] ) ?
320- . ok_or_else ( || err_unsup_format ! ( "Path libc::{} cannot be resolved." , name) ) ?
321- . not_undef ( )
322- }
323-
324- /// Helper function to get a `libc` constant as an `i32`.
325- fn eval_libc_i32 ( & mut self , name : & str ) -> InterpResult < ' tcx , i32 > {
326- self . eval_libc ( name) ?. to_i32 ( )
327- }
328-
329- /// Helper function to get the `TyLayout` of a `libc` type
330- fn libc_ty_layout ( & mut self , name : & str ) -> InterpResult < ' tcx , TyLayout < ' tcx > > {
331- let this = self . eval_context_mut ( ) ;
332- let ty = this. resolve_path ( & [ "libc" , name] ) ?. monomorphic_ty ( * this. tcx ) ;
333- this. layout_of ( ty)
334- }
335-
336344 // Writes several `ImmTy`s contiguosly into memory. This is useful when you have to pack
337345 // different values into a struct.
338346 fn write_packed_immediates (
@@ -360,7 +368,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
360368 fn check_no_isolation ( & self , name : & str ) -> InterpResult < ' tcx > {
361369 if !self . eval_context_ref ( ) . machine . communicate {
362370 throw_unsup_format ! (
363- "`{}` not available when isolation is enabled. Pass the flag `-Zmiri-disable-isolation` to disable it. " ,
371+ "`{}` not available when isolation is enabled (pass the flag `-Zmiri-disable-isolation` to disable isolation) " ,
364372 name,
365373 )
366374 }
@@ -416,13 +424,13 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
416424 AlreadyExists => "EEXIST" ,
417425 WouldBlock => "EWOULDBLOCK" ,
418426 _ => {
419- throw_unsup_format ! ( "The {} error cannot be transformed into a raw os error" , e)
427+ throw_unsup_format ! ( "io error {} cannot be transformed into a raw os error" , e)
420428 }
421429 } ) ?
422430 } else {
423431 // FIXME: we have to implement the Windows equivalent of this.
424432 throw_unsup_format ! (
425- "Setting the last OS error from an io::Error is unsupported for {}." ,
433+ "setting the last OS error from an io::Error is unsupported for {}." ,
426434 target. target_os
427435 )
428436 } ;
@@ -531,7 +539,7 @@ pub fn immty_from_int_checked<'tcx>(
531539) -> InterpResult < ' tcx , ImmTy < ' tcx , Tag > > {
532540 let int = int. into ( ) ;
533541 Ok ( ImmTy :: try_from_int ( int, layout) . ok_or_else ( || {
534- err_unsup_format ! ( "Signed value {:#x} does not fit in {} bits" , int, layout. size. bits( ) )
542+ err_unsup_format ! ( "signed value {:#x} does not fit in {} bits" , int, layout. size. bits( ) )
535543 } ) ?)
536544}
537545
@@ -541,6 +549,6 @@ pub fn immty_from_uint_checked<'tcx>(
541549) -> InterpResult < ' tcx , ImmTy < ' tcx , Tag > > {
542550 let int = int. into ( ) ;
543551 Ok ( ImmTy :: try_from_uint ( int, layout) . ok_or_else ( || {
544- err_unsup_format ! ( "Signed value {:#x} does not fit in {} bits" , int, layout. size. bits( ) )
552+ err_unsup_format ! ( "unsigned value {:#x} does not fit in {} bits" , int, layout. size. bits( ) )
545553 } ) ?)
546554}
0 commit comments