]> git.lizzy.rs Git - rust.git/blob - src/librustc_mir/interpret/machine.rs
miri/CTFE refactor
[rust.git] / src / librustc_mir / interpret / machine.rs
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
5 use std::hash::Hash;
6
7 use rustc::mir::interpret::{AllocId, EvalResult, Scalar, Pointer, AccessKind, GlobalId};
8 use super::{EvalContext, PlaceTy, OpTy, Memory};
9
10 use rustc::mir;
11 use rustc::ty::{self, layout::TyLayout};
12 use rustc::ty::layout::Size;
13 use syntax::source_map::Span;
14 use syntax::ast::Mutability;
15
16 /// Methods of this trait signifies a point where CTFE evaluation would fail
17 /// and some use case dependent behaviour can instead be applied
18 pub trait Machine<'mir, 'tcx>: Clone + Eq + Hash {
19     /// Additional data that can be accessed via the Memory
20     type MemoryData: Clone + Eq + Hash;
21
22     /// Additional memory kinds a machine wishes to distinguish from the builtin ones
23     type MemoryKinds: ::std::fmt::Debug + PartialEq + Copy + Clone;
24
25     /// Entry point to all function calls.
26     ///
27     /// Returns Ok(true) when the function was handled completely
28     /// e.g. due to missing mir
29     ///
30     /// Returns Ok(false) if a new stack frame was pushed
31     fn eval_fn_call<'a>(
32         ecx: &mut EvalContext<'a, 'mir, 'tcx, Self>,
33         instance: ty::Instance<'tcx>,
34         destination: Option<(PlaceTy<'tcx>, mir::BasicBlock)>,
35         args: &[OpTy<'tcx>],
36         span: Span,
37     ) -> EvalResult<'tcx, bool>;
38
39     /// directly process an intrinsic without pushing a stack frame.
40     fn call_intrinsic<'a>(
41         ecx: &mut EvalContext<'a, 'mir, 'tcx, Self>,
42         instance: ty::Instance<'tcx>,
43         args: &[OpTy<'tcx>],
44         dest: PlaceTy<'tcx>,
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>(
55         ecx: &EvalContext<'a, 'mir, 'tcx, Self>,
56         bin_op: mir::BinOp,
57         left: Scalar,
58         left_layout: TyLayout<'tcx>,
59         right: Scalar,
60         right_layout: TyLayout<'tcx>,
61     ) -> EvalResult<'tcx, Option<(Scalar, bool)>>;
62
63     /// Called when trying to mark machine defined `MemoryKinds` as static
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>;
76
77     /// Heap allocations via the `box` keyword
78     ///
79     /// Returns a pointer to the allocated memory
80     fn box_alloc<'a>(
81         ecx: &mut EvalContext<'a, 'mir, 'tcx, Self>,
82         dest: PlaceTy<'tcx>,
83     ) -> EvalResult<'tcx>;
84
85     /// Called when trying to access a global declared with a `linkage` attribute
86     fn global_item_with_linkage<'a>(
87         ecx: &mut EvalContext<'a, 'mir, 'tcx, Self>,
88         instance: ty::Instance<'tcx>,
89         mutability: Mutability,
90     ) -> EvalResult<'tcx>;
91
92     fn check_locks<'a>(
93         _mem: &Memory<'a, 'mir, 'tcx, Self>,
94         _ptr: Pointer,
95         _size: Size,
96         _access: AccessKind,
97     ) -> EvalResult<'tcx> {
98         Ok(())
99     }
100
101     fn add_lock<'a>(
102         _mem: &mut Memory<'a, 'mir, 'tcx, Self>,
103         _id: AllocId,
104     ) {}
105
106     fn free_lock<'a>(
107         _mem: &mut Memory<'a, 'mir, 'tcx, Self>,
108         _id: AllocId,
109         _len: u64,
110     ) -> EvalResult<'tcx> {
111         Ok(())
112     }
113
114     fn end_region<'a>(
115         _ecx: &mut EvalContext<'a, 'mir, 'tcx, Self>,
116         _reg: Option<::rustc::middle::region::Scope>,
117     ) -> EvalResult<'tcx> {
118         Ok(())
119     }
120
121     fn validation_op<'a>(
122         _ecx: &mut EvalContext<'a, 'mir, 'tcx, Self>,
123         _op: ::rustc::mir::ValidationOp,
124         _operand: &::rustc::mir::ValidationOperand<'tcx, ::rustc::mir::Place<'tcx>>,
125     ) -> EvalResult<'tcx> {
126         Ok(())
127     }
128 }