]>
Commit | Line | Data |
---|---|---|
ea8adc8c XL |
1 | //! This module contains everything needed to instantiate an interpreter. |
2 | //! This separation exists to ensure that no fancy miri features like | |
3 | //! interpreting common C functions leak into CTFE. | |
4 | ||
94b46f34 | 5 | use rustc::mir::interpret::{AllocId, EvalResult, Scalar, Pointer, AccessKind, GlobalId}; |
ff7c6d11 | 6 | use super::{EvalContext, Place, ValTy, Memory}; |
ea8adc8c | 7 | |
ff7c6d11 XL |
8 | use rustc::mir; |
9 | use rustc::ty::{self, Ty}; | |
94b46f34 | 10 | use rustc::ty::layout::Size; |
ea8adc8c XL |
11 | use syntax::codemap::Span; |
12 | use syntax::ast::Mutability; | |
13 | ||
14 | /// Methods of this trait signifies a point where CTFE evaluation would fail | |
15 | /// and some use case dependent behaviour can instead be applied | |
0531ce1d | 16 | pub trait Machine<'mir, 'tcx>: Sized { |
ea8adc8c XL |
17 | /// Additional data that can be accessed via the Memory |
18 | type MemoryData; | |
19 | ||
20 | /// Additional memory kinds a machine wishes to distinguish from the builtin ones | |
21 | type MemoryKinds: ::std::fmt::Debug + PartialEq + Copy + Clone; | |
22 | ||
23 | /// Entry point to all function calls. | |
24 | /// | |
25 | /// Returns Ok(true) when the function was handled completely | |
26 | /// e.g. due to missing mir | |
27 | /// | |
28 | /// Returns Ok(false) if a new stack frame was pushed | |
29 | fn eval_fn_call<'a>( | |
0531ce1d | 30 | ecx: &mut EvalContext<'a, 'mir, 'tcx, Self>, |
ea8adc8c | 31 | instance: ty::Instance<'tcx>, |
ff7c6d11 | 32 | destination: Option<(Place, mir::BasicBlock)>, |
ea8adc8c XL |
33 | args: &[ValTy<'tcx>], |
34 | span: Span, | |
35 | sig: ty::FnSig<'tcx>, | |
36 | ) -> EvalResult<'tcx, bool>; | |
37 | ||
38 | /// directly process an intrinsic without pushing a stack frame. | |
39 | fn call_intrinsic<'a>( | |
0531ce1d | 40 | ecx: &mut EvalContext<'a, 'mir, 'tcx, Self>, |
ea8adc8c XL |
41 | instance: ty::Instance<'tcx>, |
42 | args: &[ValTy<'tcx>], | |
ff7c6d11 XL |
43 | dest: Place, |
44 | dest_layout: ty::layout::TyLayout<'tcx>, | |
ea8adc8c XL |
45 | target: mir::BasicBlock, |
46 | ) -> EvalResult<'tcx>; | |
47 | ||
48 | /// Called for all binary operations except on float types. | |
49 | /// | |
50 | /// Returns `None` if the operation should be handled by the integer | |
51 | /// op code in order to share more code between machines | |
52 | /// | |
53 | /// Returns a (value, overflowed) pair if the operation succeeded | |
54 | fn try_ptr_op<'a>( | |
0531ce1d | 55 | ecx: &EvalContext<'a, 'mir, 'tcx, Self>, |
ea8adc8c | 56 | bin_op: mir::BinOp, |
94b46f34 | 57 | left: Scalar, |
ff7c6d11 | 58 | left_ty: Ty<'tcx>, |
94b46f34 | 59 | right: Scalar, |
ff7c6d11 | 60 | right_ty: Ty<'tcx>, |
94b46f34 | 61 | ) -> EvalResult<'tcx, Option<(Scalar, bool)>>; |
ea8adc8c XL |
62 | |
63 | /// Called when trying to mark machine defined `MemoryKinds` as static | |
0531ce1d XL |
64 | fn mark_static_initialized<'a>( |
65 | _mem: &mut Memory<'a, 'mir, 'tcx, Self>, | |
66 | _id: AllocId, | |
67 | _mutability: Mutability, | |
68 | ) -> EvalResult<'tcx, bool>; | |
69 | ||
70 | /// Called when requiring a pointer to a static. Non const eval can | |
71 | /// create a mutable memory location for `static mut` | |
72 | fn init_static<'a>( | |
73 | ecx: &mut EvalContext<'a, 'mir, 'tcx, Self>, | |
74 | cid: GlobalId<'tcx>, | |
75 | ) -> EvalResult<'tcx, AllocId>; | |
ea8adc8c XL |
76 | |
77 | /// Heap allocations via the `box` keyword | |
78 | /// | |
79 | /// Returns a pointer to the allocated memory | |
80 | fn box_alloc<'a>( | |
0531ce1d | 81 | ecx: &mut EvalContext<'a, 'mir, 'tcx, Self>, |
ff7c6d11 XL |
82 | ty: Ty<'tcx>, |
83 | dest: Place, | |
84 | ) -> EvalResult<'tcx>; | |
ea8adc8c XL |
85 | |
86 | /// Called when trying to access a global declared with a `linkage` attribute | |
87 | fn global_item_with_linkage<'a>( | |
0531ce1d | 88 | ecx: &mut EvalContext<'a, 'mir, 'tcx, Self>, |
ea8adc8c XL |
89 | instance: ty::Instance<'tcx>, |
90 | mutability: Mutability, | |
91 | ) -> EvalResult<'tcx>; | |
ff7c6d11 XL |
92 | |
93 | fn check_locks<'a>( | |
0531ce1d | 94 | _mem: &Memory<'a, 'mir, 'tcx, Self>, |
94b46f34 XL |
95 | _ptr: Pointer, |
96 | _size: Size, | |
ff7c6d11 XL |
97 | _access: AccessKind, |
98 | ) -> EvalResult<'tcx> { | |
99 | Ok(()) | |
100 | } | |
101 | ||
102 | fn add_lock<'a>( | |
0531ce1d | 103 | _mem: &mut Memory<'a, 'mir, 'tcx, Self>, |
2c00a5a8 | 104 | _id: AllocId, |
ff7c6d11 XL |
105 | ) {} |
106 | ||
107 | fn free_lock<'a>( | |
0531ce1d | 108 | _mem: &mut Memory<'a, 'mir, 'tcx, Self>, |
2c00a5a8 | 109 | _id: AllocId, |
ff7c6d11 XL |
110 | _len: u64, |
111 | ) -> EvalResult<'tcx> { | |
112 | Ok(()) | |
113 | } | |
114 | ||
115 | fn end_region<'a>( | |
0531ce1d | 116 | _ecx: &mut EvalContext<'a, 'mir, 'tcx, Self>, |
ff7c6d11 XL |
117 | _reg: Option<::rustc::middle::region::Scope>, |
118 | ) -> EvalResult<'tcx> { | |
119 | Ok(()) | |
120 | } | |
121 | ||
122 | fn validation_op<'a>( | |
0531ce1d | 123 | _ecx: &mut EvalContext<'a, 'mir, 'tcx, Self>, |
ff7c6d11 XL |
124 | _op: ::rustc::mir::ValidationOp, |
125 | _operand: &::rustc::mir::ValidationOperand<'tcx, ::rustc::mir::Place<'tcx>>, | |
126 | ) -> EvalResult<'tcx> { | |
127 | Ok(()) | |
128 | } | |
ea8adc8c | 129 | } |