@@ -20,21 +20,16 @@ use std::collections::VecDeque;
20
20
use std:: hash:: { Hash , Hasher } ;
21
21
use std:: ptr;
22
22
23
- use rustc:: ty:: Instance ;
24
- use rustc:: ty:: query:: TyCtxtAt ;
25
- use rustc:: ty:: layout:: { self , Align , TargetDataLayout , Size } ;
26
- use rustc:: mir:: interpret:: { Pointer , AllocId , Allocation , ScalarMaybeUndef ,
23
+ use rustc:: ty:: { self , Instance , query:: TyCtxtAt } ;
24
+ use rustc:: ty:: layout:: { self , Align , TargetDataLayout , Size , HasDataLayout } ;
25
+ use rustc:: mir:: interpret:: { Pointer , AllocId , Allocation , ScalarMaybeUndef , GlobalId ,
27
26
EvalResult , Scalar , EvalErrorKind , AllocType , truncate} ;
28
27
pub use rustc:: mir:: interpret:: { write_target_uint, read_target_uint} ;
29
28
use rustc_data_structures:: fx:: { FxHashSet , FxHashMap , FxHasher } ;
30
29
31
30
use syntax:: ast:: Mutability ;
32
31
33
- use super :: { EvalContext , Machine , IsStatic , static_alloc} ;
34
-
35
- ////////////////////////////////////////////////////////////////////////////////
36
- // Allocations and pointers
37
- ////////////////////////////////////////////////////////////////////////////////
32
+ use super :: { Machine , IsStatic } ;
38
33
39
34
#[ derive( Debug , PartialEq , Eq , Copy , Clone , Hash ) ]
40
35
pub enum MemoryKind < T > {
@@ -53,10 +48,6 @@ impl<T: IsStatic> IsStatic for MemoryKind<T> {
53
48
}
54
49
}
55
50
56
- ////////////////////////////////////////////////////////////////////////////////
57
- // Top-level interpreter memory
58
- ////////////////////////////////////////////////////////////////////////////////
59
-
60
51
#[ derive( Clone ) ]
61
52
pub struct Memory < ' a , ' mir , ' tcx : ' a + ' mir , M : Machine < ' mir , ' tcx > > {
62
53
/// Additional data required by the Machine
@@ -70,6 +61,13 @@ pub struct Memory<'a, 'mir, 'tcx: 'a + 'mir, M: Machine<'mir, 'tcx>> {
70
61
pub tcx : TyCtxtAt < ' a , ' tcx , ' tcx > ,
71
62
}
72
63
64
+ impl < ' a , ' mir , ' tcx , M : Machine < ' mir , ' tcx > > HasDataLayout for & ' a Memory < ' a , ' mir , ' tcx , M > {
65
+ #[ inline]
66
+ fn data_layout ( & self ) -> & TargetDataLayout {
67
+ & self . tcx . data_layout
68
+ }
69
+ }
70
+
73
71
impl < ' a , ' mir , ' tcx , M > Eq for Memory < ' a , ' mir , ' tcx , M >
74
72
where M : Machine < ' mir , ' tcx > ,
75
73
' tcx : ' a + ' mir ,
@@ -122,6 +120,45 @@ impl<'a, 'mir, 'tcx, M> Hash for Memory<'a, 'mir, 'tcx, M>
122
120
}
123
121
}
124
122
123
+ /// Helper function to obtain the global (tcx) allocation for a static
124
+ fn const_eval_static < ' a , ' mir , ' tcx , M : Machine < ' mir , ' tcx > > (
125
+ tcx : TyCtxtAt < ' a , ' tcx , ' tcx > ,
126
+ id : AllocId
127
+ ) -> EvalResult < ' tcx , & ' tcx Allocation > {
128
+ let alloc = tcx. alloc_map . lock ( ) . get ( id) ;
129
+ let def_id = match alloc {
130
+ Some ( AllocType :: Memory ( mem) ) => {
131
+ return Ok ( mem)
132
+ }
133
+ Some ( AllocType :: Function ( ..) ) => {
134
+ return err ! ( DerefFunctionPointer )
135
+ }
136
+ Some ( AllocType :: Static ( did) ) => {
137
+ did
138
+ }
139
+ None =>
140
+ return err ! ( DanglingPointerDeref ) ,
141
+ } ;
142
+ // We got a "lazy" static that has not been computed yet, do some work
143
+ trace ! ( "static_alloc: Need to compute {:?}" , def_id) ;
144
+ if tcx. is_foreign_item ( def_id) {
145
+ return M :: find_foreign_static ( tcx, def_id) ;
146
+ }
147
+ let instance = Instance :: mono ( tcx. tcx , def_id) ;
148
+ let gid = GlobalId {
149
+ instance,
150
+ promoted : None ,
151
+ } ;
152
+ tcx. const_eval ( ty:: ParamEnv :: reveal_all ( ) . and ( gid) ) . map_err ( |err| {
153
+ // no need to report anything, the const_eval call takes care of that for statics
154
+ assert ! ( tcx. is_static( def_id) . is_some( ) ) ;
155
+ EvalErrorKind :: ReferencedConstant ( err) . into ( )
156
+ } ) . map ( |val| {
157
+ // FIXME We got our static (will be a ByRef), now we make a *copy*?!?
158
+ tcx. const_to_allocation ( val)
159
+ } )
160
+ }
161
+
125
162
impl < ' a , ' mir , ' tcx , M : Machine < ' mir , ' tcx > > Memory < ' a , ' mir , ' tcx , M > {
126
163
pub fn new ( tcx : TyCtxtAt < ' a , ' tcx , ' tcx > , data : M :: MemoryData ) -> Self {
127
164
Memory {
@@ -322,7 +359,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
322
359
Some ( alloc) => Ok ( & alloc. 1 ) ,
323
360
// No need to make any copies, just provide read access to the global static
324
361
// memory in tcx.
325
- None => static_alloc ( self . tcx , id) ,
362
+ None => const_eval_static :: < M > ( self . tcx , id) ,
326
363
}
327
364
}
328
365
@@ -588,7 +625,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
588
625
id : AllocId ,
589
626
kind : MemoryKind < M :: MemoryKinds > ,
590
627
) -> EvalResult < ' tcx > {
591
- let alloc = static_alloc ( self . tcx , id) ?;
628
+ let alloc = const_eval_static :: < M > ( self . tcx , id) ?;
592
629
if alloc. mutability == Mutability :: Immutable {
593
630
return err ! ( ModifiedConstantMemory ) ;
594
631
}
@@ -980,49 +1017,3 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
980
1017
Ok ( ( ) )
981
1018
}
982
1019
}
983
-
984
- ////////////////////////////////////////////////////////////////////////////////
985
- // Unaligned accesses
986
- ////////////////////////////////////////////////////////////////////////////////
987
-
988
- pub trait HasMemory < ' a , ' mir , ' tcx : ' a + ' mir , M : Machine < ' mir , ' tcx > > {
989
- fn memory_mut ( & mut self ) -> & mut Memory < ' a , ' mir , ' tcx , M > ;
990
- fn memory ( & self ) -> & Memory < ' a , ' mir , ' tcx , M > ;
991
- }
992
-
993
- impl < ' a , ' mir , ' tcx , M > HasMemory < ' a , ' mir , ' tcx , M > for Memory < ' a , ' mir , ' tcx , M >
994
- where M : Machine < ' mir , ' tcx >
995
- {
996
- #[ inline]
997
- fn memory_mut ( & mut self ) -> & mut Memory < ' a , ' mir , ' tcx , M > {
998
- self
999
- }
1000
-
1001
- #[ inline]
1002
- fn memory ( & self ) -> & Memory < ' a , ' mir , ' tcx , M > {
1003
- self
1004
- }
1005
- }
1006
-
1007
- impl < ' a , ' mir , ' tcx , M > HasMemory < ' a , ' mir , ' tcx , M > for EvalContext < ' a , ' mir , ' tcx , M >
1008
- where M : Machine < ' mir , ' tcx >
1009
- {
1010
- #[ inline]
1011
- fn memory_mut ( & mut self ) -> & mut Memory < ' a , ' mir , ' tcx , M > {
1012
- & mut self . memory
1013
- }
1014
-
1015
- #[ inline]
1016
- fn memory ( & self ) -> & Memory < ' a , ' mir , ' tcx , M > {
1017
- & self . memory
1018
- }
1019
- }
1020
-
1021
- impl < ' a , ' mir , ' tcx , M > layout:: HasDataLayout for & ' a Memory < ' a , ' mir , ' tcx , M >
1022
- where M : Machine < ' mir , ' tcx >
1023
- {
1024
- #[ inline]
1025
- fn data_layout ( & self ) -> & TargetDataLayout {
1026
- & self . tcx . data_layout
1027
- }
1028
- }
0 commit comments