@@ -367,31 +367,43 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
367
367
368
368
// Only trait methods can have a Self parameter.
369
369
370
+ // Intercept some methods (even if we can find MIR for them)
371
+ if let ty:: InstanceDef :: Item ( def_id) = instance. def {
372
+ match & self . tcx . item_path_str ( def_id) [ ..] {
373
+ "std::sys::imp::fast_thread_local::register_dtor" => {
374
+ // Just don't execute this one, we don't handle all this thread-local stuff anyway.
375
+ self . goto_block ( destination. unwrap ( ) . 1 ) ;
376
+ return Ok ( true )
377
+ }
378
+ _ => { }
379
+ }
380
+ }
381
+
370
382
let mir = match self . load_mir ( instance. def ) {
371
383
Ok ( mir) => mir,
372
384
Err ( EvalError :: NoMirFor ( path) ) => {
373
- match & path[ ..] {
374
- // let's just ignore all output for now
385
+ return match & path[ ..] {
386
+ // Intercept some methods if we cannot find their MIR.
375
387
"std::io::_print" => {
388
+ trace ! ( "Ignoring output." ) ;
376
389
self . goto_block ( destination. unwrap ( ) . 1 ) ;
377
- return Ok ( true ) ;
390
+ Ok ( true )
378
391
} ,
379
- "std::thread::Builder::new" => return Err ( EvalError :: Unimplemented ( "miri does not support threading" . to_owned ( ) ) ) ,
380
- "std::env::args" => return Err ( EvalError :: Unimplemented ( "miri does not support program arguments" . to_owned ( ) ) ) ,
392
+ "std::thread::Builder::new" => Err ( EvalError :: Unimplemented ( "miri does not support threading" . to_owned ( ) ) ) ,
393
+ "std::env::args" => Err ( EvalError :: Unimplemented ( "miri does not support program arguments" . to_owned ( ) ) ) ,
381
394
"std::panicking::rust_panic_with_hook" |
382
- "std::rt::begin_panic_fmt" => return Err ( EvalError :: Panic ) ,
395
+ "std::rt::begin_panic_fmt" => Err ( EvalError :: Panic ) ,
383
396
"std::panicking::panicking" |
384
397
"std::rt::panicking" => {
385
398
let ( lval, block) = destination. expect ( "std::rt::panicking does not diverge" ) ;
386
399
// we abort on panic -> `std::rt::panicking` always returns false
387
400
let bool = self . tcx . types . bool ;
388
401
self . write_primval ( lval, PrimVal :: from_bool ( false ) , bool) ?;
389
402
self . goto_block ( block) ;
390
- return Ok ( true ) ;
403
+ Ok ( true )
391
404
}
392
- _ => { } ,
393
- }
394
- return Err ( EvalError :: NoMirFor ( path) ) ;
405
+ _ => Err ( EvalError :: NoMirFor ( path) ) ,
406
+ } ;
395
407
} ,
396
408
Err ( other) => return Err ( other) ,
397
409
} ;
@@ -569,6 +581,24 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
569
581
}
570
582
self . write_value ( Value :: ByVal ( PrimVal :: Bytes ( 0 ) ) , dest, dest_ty) ?;
571
583
}
584
+
585
+ "write" => {
586
+ let fd = self . value_to_primval ( args[ 0 ] , usize) ?. to_u64 ( ) ?;
587
+ let buf = args[ 1 ] . read_ptr ( & self . memory ) ?;
588
+ let n = self . value_to_primval ( args[ 2 ] , usize) ?. to_u64 ( ) ?;
589
+ trace ! ( "Called write({:?}, {:?}, {:?})" , fd, buf, n) ;
590
+ let result = if fd == 1 { // stdout
591
+ use std:: io:: { self , Write } ;
592
+
593
+ let buf_cont = self . memory . read_bytes ( buf, n) ?;
594
+ let res = io:: stdout ( ) . write ( buf_cont) ;
595
+ match res { Ok ( n) => n as isize , Err ( _) => -1 }
596
+ } else {
597
+ info ! ( "Ignored output to FD {}" , fd) ;
598
+ n as isize // pretend it all went well
599
+ } ; // now result is the value we return back to the program
600
+ self . write_primval ( dest, PrimVal :: Bytes ( result as u128 ) , dest_ty) ?;
601
+ }
572
602
573
603
// unix panic code inside libstd will read the return value of this function
574
604
"pthread_rwlock_rdlock" => {
0 commit comments