@@ -7,11 +7,11 @@ use std::hash::Hash;
7
7
8
8
use rustc:: hir:: def_id:: DefId ;
9
9
use rustc:: mir;
10
- use rustc:: ty:: { self , query :: TyCtxtAt } ;
10
+ use rustc:: ty:: { self , TyCtxt } ;
11
11
12
12
use super :: {
13
- Allocation , AllocId , InterpResult , Scalar , AllocationExtra ,
14
- InterpCx , PlaceTy , OpTy , ImmTy , MemoryKind , Pointer , Memory
13
+ Allocation , AllocId , InterpResult , InterpError , Scalar , AllocationExtra ,
14
+ InterpCx , PlaceTy , OpTy , ImmTy , MemoryKind , Pointer , Memory ,
15
15
} ;
16
16
17
17
/// Whether this kind of memory is allowed to leak
@@ -67,6 +67,11 @@ pub trait Machine<'mir, 'tcx>: Sized {
67
67
/// The `default()` is used for pointers to consts, statics, vtables and functions.
68
68
type PointerTag : :: std:: fmt:: Debug + Copy + Eq + Hash + ' static ;
69
69
70
+ /// Machines can define extra (non-instance) things that represent values of function pointers.
71
+ /// For example, Miri uses this to return a fucntion pointer from `dlsym`
72
+ /// that can later be called to execute the right thing.
73
+ type ExtraFnVal : :: std:: fmt:: Debug + Copy ;
74
+
70
75
/// Extra data stored in every call frame.
71
76
type FrameExtra ;
72
77
@@ -119,6 +124,16 @@ pub trait Machine<'mir, 'tcx>: Sized {
119
124
ret : Option < mir:: BasicBlock > ,
120
125
) -> InterpResult < ' tcx , Option < & ' mir mir:: Body < ' tcx > > > ;
121
126
127
+ /// Execute `fn_val`. it is the hook's responsibility to advance the instruction
128
+ /// pointer as appropriate.
129
+ fn call_extra_fn (
130
+ ecx : & mut InterpCx < ' mir , ' tcx , Self > ,
131
+ fn_val : Self :: ExtraFnVal ,
132
+ args : & [ OpTy < ' tcx , Self :: PointerTag > ] ,
133
+ dest : Option < PlaceTy < ' tcx , Self :: PointerTag > > ,
134
+ ret : Option < mir:: BasicBlock > ,
135
+ ) -> InterpResult < ' tcx > ;
136
+
122
137
/// Directly process an intrinsic without pushing a stack frame.
123
138
/// If this returns successfully, the engine will take care of jumping to the next block.
124
139
fn call_intrinsic (
@@ -136,8 +151,8 @@ pub trait Machine<'mir, 'tcx>: Sized {
136
151
///
137
152
/// This allocation will then be fed to `tag_allocation` to initialize the "extra" state.
138
153
fn find_foreign_static (
154
+ tcx : TyCtxt < ' tcx > ,
139
155
def_id : DefId ,
140
- tcx : TyCtxtAt < ' tcx > ,
141
156
) -> InterpResult < ' tcx , Cow < ' tcx , Allocation > > ;
142
157
143
158
/// Called for all binary operations on integer(-like) types when one operand is a pointer
@@ -174,10 +189,10 @@ pub trait Machine<'mir, 'tcx>: Sized {
174
189
/// For static allocations, the tag returned must be the same as the one returned by
175
190
/// `tag_static_base_pointer`.
176
191
fn tag_allocation < ' b > (
192
+ memory_extra : & Self :: MemoryExtra ,
177
193
id : AllocId ,
178
194
alloc : Cow < ' b , Allocation > ,
179
195
kind : Option < MemoryKind < Self :: MemoryKinds > > ,
180
- memory : & Memory < ' mir , ' tcx , Self > ,
181
196
) -> ( Cow < ' b , Allocation < Self :: PointerTag , Self :: AllocExtra > > , Self :: PointerTag ) ;
182
197
183
198
/// Return the "base" tag for the given static allocation: the one that is used for direct
@@ -186,8 +201,8 @@ pub trait Machine<'mir, 'tcx>: Sized {
186
201
/// Be aware that requesting the `Allocation` for that `id` will lead to cycles
187
202
/// for cyclic statics!
188
203
fn tag_static_base_pointer (
204
+ memory_extra : & Self :: MemoryExtra ,
189
205
id : AllocId ,
190
- memory : & Memory < ' mir , ' tcx , Self > ,
191
206
) -> Self :: PointerTag ;
192
207
193
208
/// Executes a retagging operation
@@ -209,20 +224,22 @@ pub trait Machine<'mir, 'tcx>: Sized {
209
224
extra : Self :: FrameExtra ,
210
225
) -> InterpResult < ' tcx > ;
211
226
227
+ #[ inline( always) ]
212
228
fn int_to_ptr (
213
- int : u64 ,
214
229
_mem : & Memory < ' mir , ' tcx , Self > ,
230
+ int : u64 ,
215
231
) -> InterpResult < ' tcx , Pointer < Self :: PointerTag > > {
216
- if int == 0 {
217
- err ! ( InvalidNullPointerUsage )
232
+ Err ( ( if int == 0 {
233
+ InterpError :: InvalidNullPointerUsage
218
234
} else {
219
- err ! ( ReadBytesAsPointer )
220
- }
235
+ InterpError :: ReadBytesAsPointer
236
+ } ) . into ( ) )
221
237
}
222
238
239
+ #[ inline( always) ]
223
240
fn ptr_to_int (
224
- _ptr : Pointer < Self :: PointerTag > ,
225
241
_mem : & Memory < ' mir , ' tcx , Self > ,
242
+ _ptr : Pointer < Self :: PointerTag > ,
226
243
) -> InterpResult < ' tcx , u64 > {
227
244
err ! ( ReadPointerAsBytes )
228
245
}
0 commit comments