@@ -7,7 +7,6 @@ use std::collections::BTreeMap;
7
7
use std:: io:: { self , ErrorKind , IsTerminal , Read , SeekFrom , Write } ;
8
8
use std:: rc:: Rc ;
9
9
10
- use rustc_middle:: ty:: TyCtxt ;
11
10
use rustc_target:: abi:: Size ;
12
11
13
12
use crate :: shims:: unix:: * ;
@@ -22,7 +21,7 @@ pub trait FileDescription: std::fmt::Debug + Any {
22
21
& mut self ,
23
22
_communicate_allowed : bool ,
24
23
_bytes : & mut [ u8 ] ,
25
- _tcx : TyCtxt < ' tcx > ,
24
+ _ecx : & mut MiriInterpCx < ' _ , ' tcx > ,
26
25
) -> InterpResult < ' tcx , io:: Result < usize > > {
27
26
throw_unsup_format ! ( "cannot read from {}" , self . name( ) ) ;
28
27
}
@@ -32,7 +31,7 @@ pub trait FileDescription: std::fmt::Debug + Any {
32
31
& mut self ,
33
32
_communicate_allowed : bool ,
34
33
_bytes : & [ u8 ] ,
35
- _tcx : TyCtxt < ' tcx > ,
34
+ _ecx : & mut MiriInterpCx < ' _ , ' tcx > ,
36
35
) -> InterpResult < ' tcx , io:: Result < usize > > {
37
36
throw_unsup_format ! ( "cannot write to {}" , self . name( ) ) ;
38
37
}
@@ -82,7 +81,7 @@ impl FileDescription for io::Stdin {
82
81
& mut self ,
83
82
communicate_allowed : bool ,
84
83
bytes : & mut [ u8 ] ,
85
- _tcx : TyCtxt < ' tcx > ,
84
+ _ecx : & mut MiriInterpCx < ' _ , ' tcx > ,
86
85
) -> InterpResult < ' tcx , io:: Result < usize > > {
87
86
if !communicate_allowed {
88
87
// We want isolation mode to be deterministic, so we have to disallow all reads, even stdin.
@@ -105,7 +104,7 @@ impl FileDescription for io::Stdout {
105
104
& mut self ,
106
105
_communicate_allowed : bool ,
107
106
bytes : & [ u8 ] ,
108
- _tcx : TyCtxt < ' tcx > ,
107
+ _ecx : & mut MiriInterpCx < ' _ , ' tcx > ,
109
108
) -> InterpResult < ' tcx , io:: Result < usize > > {
110
109
// We allow writing to stderr even with isolation enabled.
111
110
let result = Write :: write ( self , bytes) ;
@@ -133,7 +132,7 @@ impl FileDescription for io::Stderr {
133
132
& mut self ,
134
133
_communicate_allowed : bool ,
135
134
bytes : & [ u8 ] ,
136
- _tcx : TyCtxt < ' tcx > ,
135
+ _ecx : & mut MiriInterpCx < ' _ , ' tcx > ,
137
136
) -> InterpResult < ' tcx , io:: Result < usize > > {
138
137
// We allow writing to stderr even with isolation enabled.
139
138
// No need to flush, stderr is not buffered.
@@ -158,7 +157,7 @@ impl FileDescription for NullOutput {
158
157
& mut self ,
159
158
_communicate_allowed : bool ,
160
159
bytes : & [ u8 ] ,
161
- _tcx : TyCtxt < ' tcx > ,
160
+ _ecx : & mut MiriInterpCx < ' _ , ' tcx > ,
162
161
) -> InterpResult < ' tcx , io:: Result < usize > > {
163
162
// We just don't write anything, but report to the user that we did.
164
163
Ok ( Ok ( bytes. len ( ) ) )
@@ -173,6 +172,14 @@ impl FileDescriptor {
173
172
FileDescriptor ( Rc :: new ( RefCell :: new ( Box :: new ( fd) ) ) )
174
173
}
175
174
175
+ pub fn borrow ( & self ) -> Ref < ' _ , dyn FileDescription > {
176
+ Ref :: map ( self . 0 . borrow ( ) , |fd| fd. as_ref ( ) )
177
+ }
178
+
179
+ pub fn borrow_mut ( & self ) -> RefMut < ' _ , dyn FileDescription > {
180
+ RefMut :: map ( self . 0 . borrow_mut ( ) , |fd| fd. as_mut ( ) )
181
+ }
182
+
176
183
pub fn close < ' ctx > ( self , communicate_allowed : bool ) -> InterpResult < ' ctx , io:: Result < ( ) > > {
177
184
// Destroy this `Rc` using `into_inner` so we can call `close` instead of
178
185
// implicitly running the destructor of the file description.
@@ -242,12 +249,12 @@ impl FdTable {
242
249
243
250
pub fn get ( & self , fd : i32 ) -> Option < Ref < ' _ , dyn FileDescription > > {
244
251
let fd = self . fds . get ( & fd) ?;
245
- Some ( Ref :: map ( fd. 0 . borrow ( ) , |fd| fd . as_ref ( ) ) )
252
+ Some ( fd. borrow ( ) )
246
253
}
247
254
248
255
pub fn get_mut ( & self , fd : i32 ) -> Option < RefMut < ' _ , dyn FileDescription > > {
249
256
let fd = self . fds . get ( & fd) ?;
250
- Some ( RefMut :: map ( fd. 0 . borrow_mut ( ) , |fd| fd . as_mut ( ) ) )
257
+ Some ( fd. borrow_mut ( ) )
251
258
}
252
259
253
260
pub fn dup ( & self , fd : i32 ) -> Option < FileDescriptor > {
@@ -370,7 +377,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
370
377
. min ( u64:: try_from ( isize:: MAX ) . unwrap ( ) ) ;
371
378
let communicate = this. machine . communicate ( ) ;
372
379
373
- let Some ( mut file_descriptor) = this. machine . fds . get_mut ( fd) else {
380
+ // We temporarily dup the FD to be able to retain mutable access to `this`.
381
+ let Some ( file_descriptor) = this. machine . fds . dup ( fd) else {
374
382
trace ! ( "read: FD not found" ) ;
375
383
return this. fd_not_found ( ) ;
376
384
} ;
@@ -383,7 +391,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
383
391
// `File::read` never returns a value larger than `count`,
384
392
// so this cannot fail.
385
393
let result = file_descriptor
386
- . read ( communicate, & mut bytes, * this. tcx ) ?
394
+ . borrow_mut ( )
395
+ . read ( communicate, & mut bytes, this) ?
387
396
. map ( |c| i64:: try_from ( c) . unwrap ( ) ) ;
388
397
drop ( file_descriptor) ;
389
398
@@ -421,12 +430,14 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
421
430
let communicate = this. machine . communicate ( ) ;
422
431
423
432
let bytes = this. read_bytes_ptr_strip_provenance ( buf, Size :: from_bytes ( count) ) ?. to_owned ( ) ;
424
- let Some ( mut file_descriptor) = this. machine . fds . get_mut ( fd) else {
433
+ // We temporarily dup the FD to be able to retain mutable access to `this`.
434
+ let Some ( file_descriptor) = this. machine . fds . dup ( fd) else {
425
435
return this. fd_not_found ( ) ;
426
436
} ;
427
437
428
438
let result = file_descriptor
429
- . write ( communicate, & bytes, * this. tcx ) ?
439
+ . borrow_mut ( )
440
+ . write ( communicate, & bytes, this) ?
430
441
. map ( |c| i64:: try_from ( c) . unwrap ( ) ) ;
431
442
drop ( file_descriptor) ;
432
443
0 commit comments