1
1
use rustc:: middle:: const_val:: ConstVal ;
2
2
use rustc:: hir:: def_id:: DefId ;
3
3
use rustc:: hir:: map:: definitions:: DefPathData ;
4
- use rustc:: mir:: mir_map:: MirMap ;
5
- use rustc:: mir:: repr as mir;
4
+ use rustc:: mir;
6
5
use rustc:: traits:: Reveal ;
7
6
use rustc:: ty:: layout:: { self , Layout , Size } ;
8
7
use rustc:: ty:: subst:: { self , Subst , Substs } ;
9
8
use rustc:: ty:: { self , Ty , TyCtxt , TypeFoldable } ;
10
- use rustc:: util:: nodemap:: DefIdMap ;
11
9
use rustc_data_structures:: indexed_vec:: Idx ;
12
- use std:: cell:: RefCell ;
13
- use std:: ops:: Deref ;
14
- use std:: rc:: Rc ;
15
10
use syntax:: codemap:: { self , DUMMY_SP } ;
16
11
17
12
use error:: { EvalError , EvalResult } ;
@@ -20,44 +15,41 @@ use primval::{self, PrimVal, PrimValKind};
20
15
pub use self :: value:: Value ;
21
16
22
17
use std:: collections:: HashMap ;
18
+ use std:: cell:: Ref ;
23
19
24
20
mod step;
25
21
mod terminator;
26
22
mod cast;
27
23
mod vtable;
28
24
mod value;
29
25
26
+ pub type MirRef < ' tcx > = :: std:: cell:: Ref < ' tcx , mir:: Mir < ' tcx > > ;
27
+
30
28
pub struct EvalContext < ' a , ' tcx : ' a > {
31
29
/// The results of the type checker, from rustc.
32
30
tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
33
31
34
- /// A mapping from NodeIds to Mir, from rustc. Only contains MIR for crate-local items.
35
- mir_map : & ' a MirMap < ' tcx > ,
36
-
37
- /// A local cache from DefIds to Mir for non-crate-local items.
38
- mir_cache : RefCell < DefIdMap < Rc < mir:: Mir < ' tcx > > > > ,
39
-
40
32
/// The virtual memory system.
41
33
memory : Memory < ' a , ' tcx > ,
42
34
43
35
/// Precomputed statics, constants and promoteds.
44
36
globals : HashMap < GlobalId < ' tcx > , Global < ' tcx > > ,
45
37
46
38
/// The virtual call stack.
47
- stack : Vec < Frame < ' a , ' tcx > > ,
39
+ stack : Vec < Frame < ' tcx > > ,
48
40
49
41
/// The maximum number of stack frames allowed
50
42
stack_limit : usize ,
51
43
}
52
44
53
45
/// A stack frame.
54
- pub struct Frame < ' a , ' tcx : ' a > {
46
+ pub struct Frame < ' tcx > {
55
47
////////////////////////////////////////////////////////////////////////////////
56
48
// Function and callsite information
57
49
////////////////////////////////////////////////////////////////////////////////
58
50
59
51
/// The MIR for the function called on this frame.
60
- pub mir : CachedMir < ' a , ' tcx > ,
52
+ pub mir : MirRef < ' tcx > ,
61
53
62
54
/// The def_id of the current function.
63
55
pub def_id : DefId ,
@@ -125,12 +117,6 @@ pub enum LvalueExtra {
125
117
DowncastVariant ( usize ) ,
126
118
}
127
119
128
- #[ derive( Clone ) ]
129
- pub enum CachedMir < ' mir , ' tcx : ' mir > {
130
- Ref ( & ' mir mir:: Mir < ' tcx > ) ,
131
- Owned ( Rc < mir:: Mir < ' tcx > > )
132
- }
133
-
134
120
#[ derive( Copy , Clone , Debug , Eq , PartialEq , Hash ) ]
135
121
/// Uniquely identifies a specific constant or static
136
122
pub struct GlobalId < ' tcx > {
@@ -176,11 +162,9 @@ pub enum StackPopCleanup {
176
162
}
177
163
178
164
impl < ' a , ' tcx > EvalContext < ' a , ' tcx > {
179
- pub fn new ( tcx : TyCtxt < ' a , ' tcx , ' tcx > , mir_map : & ' a MirMap < ' tcx > , memory_size : usize , stack_limit : usize ) -> Self {
165
+ pub fn new ( tcx : TyCtxt < ' a , ' tcx , ' tcx > , memory_size : usize , stack_limit : usize ) -> Self {
180
166
EvalContext {
181
167
tcx : tcx,
182
- mir_map : mir_map,
183
- mir_cache : RefCell :: new ( DefIdMap ( ) ) ,
184
168
memory : Memory :: new ( & tcx. data_layout , memory_size) ,
185
169
globals : HashMap :: new ( ) ,
186
170
stack : Vec :: new ( ) ,
@@ -211,7 +195,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
211
195
& mut self . memory
212
196
}
213
197
214
- pub fn stack ( & self ) -> & [ Frame < ' a , ' tcx > ] {
198
+ pub fn stack ( & self ) -> & [ Frame < ' tcx > ] {
215
199
& self . stack
216
200
}
217
201
@@ -292,25 +276,12 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
292
276
ty. is_sized ( self . tcx , & self . tcx . empty_parameter_environment ( ) , DUMMY_SP )
293
277
}
294
278
295
- pub fn load_mir ( & self , def_id : DefId ) -> EvalResult < ' tcx , CachedMir < ' a , ' tcx > > {
279
+ pub fn load_mir ( & self , def_id : DefId ) -> EvalResult < ' tcx , MirRef < ' tcx > > {
296
280
trace ! ( "load mir {:?}" , def_id) ;
297
- if def_id. is_local ( ) {
298
- Ok ( CachedMir :: Ref ( self . mir_map . map . get ( & def_id) . unwrap ( ) ) )
281
+ if def_id. is_local ( ) || self . tcx . sess . cstore . is_item_mir_available ( def_id ) {
282
+ Ok ( self . tcx . item_mir ( def_id) )
299
283
} else {
300
- let mut mir_cache = self . mir_cache . borrow_mut ( ) ;
301
- if let Some ( mir) = mir_cache. get ( & def_id) {
302
- return Ok ( CachedMir :: Owned ( mir. clone ( ) ) ) ;
303
- }
304
-
305
- let cs = & self . tcx . sess . cstore ;
306
- match cs. maybe_get_item_mir ( self . tcx , def_id) {
307
- Some ( mir) => {
308
- let cached = Rc :: new ( mir) ;
309
- mir_cache. insert ( def_id, cached. clone ( ) ) ;
310
- Ok ( CachedMir :: Owned ( cached) )
311
- } ,
312
- None => Err ( EvalError :: NoMirFor ( self . tcx . item_path_str ( def_id) ) ) ,
313
- }
284
+ Err ( EvalError :: NoMirFor ( self . tcx . item_path_str ( def_id) ) )
314
285
}
315
286
}
316
287
@@ -358,7 +329,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
358
329
& mut self ,
359
330
def_id : DefId ,
360
331
span : codemap:: Span ,
361
- mir : CachedMir < ' a , ' tcx > ,
332
+ mir : MirRef < ' tcx > ,
362
333
substs : & ' tcx Substs < ' tcx > ,
363
334
return_lvalue : Lvalue < ' tcx > ,
364
335
return_to_block : StackPopCleanup ,
@@ -371,7 +342,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
371
342
let locals = vec ! [ None ; num_locals] ;
372
343
373
344
self . stack . push ( Frame {
374
- mir : mir. clone ( ) ,
345
+ mir : mir,
375
346
block : mir:: START_BLOCK ,
376
347
return_to_block : return_to_block,
377
348
return_lvalue : return_lvalue,
@@ -483,7 +454,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
483
454
let dest_ty = self . lvalue_ty ( lvalue) ;
484
455
let dest_layout = self . type_layout ( dest_ty) ;
485
456
486
- use rustc:: mir:: repr :: Rvalue :: * ;
457
+ use rustc:: mir:: Rvalue :: * ;
487
458
match * rvalue {
488
459
Use ( ref operand) => {
489
460
let value = self . eval_operand ( operand) ?;
@@ -653,7 +624,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
653
624
654
625
Cast ( kind, ref operand, cast_ty) => {
655
626
debug_assert_eq ! ( self . monomorphize( cast_ty, self . substs( ) ) , dest_ty) ;
656
- use rustc:: mir:: repr :: CastKind :: * ;
627
+ use rustc:: mir:: CastKind :: * ;
657
628
match kind {
658
629
Unsize => {
659
630
let src = self . eval_operand ( operand) ?;
@@ -812,12 +783,12 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
812
783
}
813
784
814
785
fn eval_operand ( & mut self , op : & mir:: Operand < ' tcx > ) -> EvalResult < ' tcx , Value > {
815
- use rustc:: mir:: repr :: Operand :: * ;
786
+ use rustc:: mir:: Operand :: * ;
816
787
match * op {
817
788
Consume ( ref lvalue) => self . eval_and_read_lvalue ( lvalue) ,
818
789
819
790
Constant ( mir:: Constant { ref literal, ty, .. } ) => {
820
- use rustc:: mir:: repr :: Literal ;
791
+ use rustc:: mir:: Literal ;
821
792
let value = match * literal {
822
793
Literal :: Value { ref value } => self . const_to_value ( value) ?,
823
794
@@ -883,7 +854,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
883
854
}
884
855
885
856
fn eval_lvalue ( & mut self , mir_lvalue : & mir:: Lvalue < ' tcx > ) -> EvalResult < ' tcx , Lvalue < ' tcx > > {
886
- use rustc:: mir:: repr :: Lvalue :: * ;
857
+ use rustc:: mir:: Lvalue :: * ;
887
858
let lvalue = match * mir_lvalue {
888
859
Local ( mir:: RETURN_POINTER ) => self . frame ( ) . return_lvalue ,
889
860
@@ -922,7 +893,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
922
893
let base_ty = self . lvalue_ty ( & proj. base ) ;
923
894
let base_layout = self . type_layout ( base_ty) ;
924
895
925
- use rustc:: mir:: repr :: ProjectionElem :: * ;
896
+ use rustc:: mir:: ProjectionElem :: * ;
926
897
let ( ptr, extra) = match proj. elem {
927
898
Field ( field, field_ty) => {
928
899
// FIXME(solson)
@@ -1462,16 +1433,16 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
1462
1433
Ok ( Value :: ByVal ( val) )
1463
1434
}
1464
1435
1465
- fn frame ( & self ) -> & Frame < ' a , ' tcx > {
1436
+ fn frame ( & self ) -> & Frame < ' tcx > {
1466
1437
self . stack . last ( ) . expect ( "no call frames exist" )
1467
1438
}
1468
1439
1469
- pub fn frame_mut ( & mut self ) -> & mut Frame < ' a , ' tcx > {
1440
+ pub fn frame_mut ( & mut self ) -> & mut Frame < ' tcx > {
1470
1441
self . stack . last_mut ( ) . expect ( "no call frames exist" )
1471
1442
}
1472
1443
1473
- fn mir ( & self ) -> CachedMir < ' a , ' tcx > {
1474
- self . frame ( ) . mir . clone ( )
1444
+ fn mir ( & self ) -> MirRef < ' tcx > {
1445
+ Ref :: clone ( & self . frame ( ) . mir )
1475
1446
}
1476
1447
1477
1448
fn substs ( & self ) -> & ' tcx Substs < ' tcx > {
@@ -1583,7 +1554,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
1583
1554
}
1584
1555
}
1585
1556
1586
- impl < ' a , ' tcx : ' a > Frame < ' a , ' tcx > {
1557
+ impl < ' tcx > Frame < ' tcx > {
1587
1558
pub fn get_local ( & self , local : mir:: Local ) -> Option < Value > {
1588
1559
// Subtract 1 because we don't store a value for the ReturnPointer, the local with index 0.
1589
1560
self . locals [ local. index ( ) - 1 ]
@@ -1630,34 +1601,23 @@ impl<'tcx> Lvalue<'tcx> {
1630
1601
}
1631
1602
}
1632
1603
1633
- impl < ' mir , ' tcx : ' mir > Deref for CachedMir < ' mir , ' tcx > {
1634
- type Target = mir:: Mir < ' tcx > ;
1635
- fn deref ( & self ) -> & mir:: Mir < ' tcx > {
1636
- match * self {
1637
- CachedMir :: Ref ( r) => r,
1638
- CachedMir :: Owned ( ref rc) => rc,
1639
- }
1640
- }
1641
- }
1642
-
1643
1604
pub fn eval_main < ' a , ' tcx : ' a > (
1644
1605
tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
1645
- mir_map : & ' a MirMap < ' tcx > ,
1646
1606
def_id : DefId ,
1647
1607
memory_size : usize ,
1648
1608
step_limit : u64 ,
1649
1609
stack_limit : usize ,
1650
1610
) {
1651
- let mir = mir_map . map . get ( & def_id ) . expect ( "no mir for main function" ) ;
1652
- let mut ecx = EvalContext :: new ( tcx , mir_map , memory_size , stack_limit ) ;
1611
+ let mut ecx = EvalContext :: new ( tcx , memory_size , stack_limit ) ;
1612
+ let mir = ecx . load_mir ( def_id ) . expect ( "main function's MIR not found" ) ;
1653
1613
1654
1614
ecx. push_stack_frame (
1655
1615
def_id,
1656
1616
mir. span ,
1657
- CachedMir :: Ref ( mir) ,
1617
+ mir,
1658
1618
tcx. intern_substs ( & [ ] ) ,
1659
1619
Lvalue :: from_ptr ( Pointer :: zst_ptr ( ) ) ,
1660
- StackPopCleanup :: None
1620
+ StackPopCleanup :: None ,
1661
1621
) . expect ( "could not allocate first stack frame" ) ;
1662
1622
1663
1623
for _ in 0 ..step_limit {
@@ -1695,15 +1655,15 @@ fn report(tcx: TyCtxt, ecx: &EvalContext, e: EvalError) {
1695
1655
impl < ' tcx > :: std:: panic:: RefUnwindSafe for Instance < ' tcx > { }
1696
1656
impl < ' tcx > fmt:: Display for Instance < ' tcx > {
1697
1657
fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
1698
- ppaux:: parameterized ( f, self . 1 , self . 0 , ppaux :: Ns :: Value , & [ ] )
1658
+ ppaux:: parameterized ( f, self . 1 , self . 0 , & [ ] )
1699
1659
}
1700
1660
}
1701
1661
err. span_note ( span, & format ! ( "inside call to {}" , Instance ( def_id, substs) ) ) ;
1702
1662
}
1703
1663
err. emit ( ) ;
1704
1664
}
1705
1665
1706
- pub fn run_mir_passes < ' a , ' tcx > ( tcx : TyCtxt < ' a , ' tcx , ' tcx > , mir_map : & mut MirMap < ' tcx > ) {
1666
+ pub fn run_mir_passes < ' a , ' tcx > ( tcx : TyCtxt < ' a , ' tcx , ' tcx > ) {
1707
1667
let mut passes = :: rustc:: mir:: transform:: Passes :: new ( ) ;
1708
1668
passes. push_hook ( Box :: new ( :: rustc_mir:: transform:: dump_mir:: DumpMir ) ) ;
1709
1669
passes. push_pass ( Box :: new ( :: rustc_mir:: transform:: no_landing_pads:: NoLandingPads ) ) ;
@@ -1716,7 +1676,7 @@ pub fn run_mir_passes<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, mir_map: &mut MirMa
1716
1676
passes. push_pass ( Box :: new ( :: rustc_mir:: transform:: simplify_cfg:: SimplifyCfg :: new ( "elaborate-drops" ) ) ) ;
1717
1677
passes. push_pass ( Box :: new ( :: rustc_mir:: transform:: dump_mir:: Marker ( "PreMiri" ) ) ) ;
1718
1678
1719
- passes. run_passes ( tcx, mir_map ) ;
1679
+ passes. run_passes ( tcx) ;
1720
1680
}
1721
1681
1722
1682
// TODO(solson): Upstream these methods into rustc::ty::layout.
0 commit comments