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.
7 use rustc::mir::interpret::{AllocId, EvalResult, Scalar, Pointer, AccessKind, GlobalId};
8 use super::{EvalContext, PlaceTy, OpTy, Memory};
11 use rustc::ty::{self, layout::TyLayout};
12 use rustc::ty::layout::Size;
13 use syntax::source_map::Span;
14 use syntax::ast::Mutability;
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;
22 /// Additional memory kinds a machine wishes to distinguish from the builtin ones
23 type MemoryKinds: ::std::fmt::Debug + PartialEq + Copy + Clone;
25 /// Entry point to all function calls.
27 /// Returns Ok(true) when the function was handled completely
28 /// e.g. due to missing mir
30 /// Returns Ok(false) if a new stack frame was pushed
32 ecx: &mut EvalContext<'a, 'mir, 'tcx, Self>,
33 instance: ty::Instance<'tcx>,
34 destination: Option<(PlaceTy<'tcx>, mir::BasicBlock)>,
37 ) -> EvalResult<'tcx, bool>;
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>,
45 target: mir::BasicBlock,
46 ) -> EvalResult<'tcx>;
48 /// Called for all binary operations except on float types.
50 /// Returns `None` if the operation should be handled by the integer
51 /// op code in order to share more code between machines
53 /// Returns a (value, overflowed) pair if the operation succeeded
55 ecx: &EvalContext<'a, 'mir, 'tcx, Self>,
58 left_layout: TyLayout<'tcx>,
60 right_layout: TyLayout<'tcx>,
61 ) -> EvalResult<'tcx, Option<(Scalar, bool)>>;
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>,
67 _mutability: Mutability,
68 ) -> EvalResult<'tcx, bool>;
70 /// Called when requiring a pointer to a static. Non const eval can
71 /// create a mutable memory location for `static mut`
73 ecx: &mut EvalContext<'a, 'mir, 'tcx, Self>,
75 ) -> EvalResult<'tcx, AllocId>;
77 /// Heap allocations via the `box` keyword
79 /// Returns a pointer to the allocated memory
81 ecx: &mut EvalContext<'a, 'mir, 'tcx, Self>,
83 ) -> EvalResult<'tcx>;
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>;
93 _mem: &Memory<'a, 'mir, 'tcx, Self>,
97 ) -> EvalResult<'tcx> {
102 _mem: &mut Memory<'a, 'mir, 'tcx, Self>,
107 _mem: &mut Memory<'a, 'mir, 'tcx, Self>,
110 ) -> EvalResult<'tcx> {
115 _ecx: &mut EvalContext<'a, 'mir, 'tcx, Self>,
116 _reg: Option<::rustc::middle::region::Scope>,
117 ) -> EvalResult<'tcx> {
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> {