]>
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 | ||
5 | use super::{EvalResult, EvalContext, Lvalue, PrimVal, ValTy}; | |
6 | ||
7 | use rustc::{mir, ty}; | |
8 | use syntax::codemap::Span; | |
9 | use syntax::ast::Mutability; | |
10 | ||
11 | /// Methods of this trait signifies a point where CTFE evaluation would fail | |
12 | /// and some use case dependent behaviour can instead be applied | |
13 | pub trait Machine<'tcx>: Sized { | |
14 | /// Additional data that can be accessed via the EvalContext | |
15 | type Data; | |
16 | ||
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>( | |
30 | ecx: &mut EvalContext<'a, 'tcx, Self>, | |
31 | instance: ty::Instance<'tcx>, | |
32 | destination: Option<(Lvalue, mir::BasicBlock)>, | |
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>( | |
40 | ecx: &mut EvalContext<'a, 'tcx, Self>, | |
41 | instance: ty::Instance<'tcx>, | |
42 | args: &[ValTy<'tcx>], | |
43 | dest: Lvalue, | |
44 | dest_ty: ty::Ty<'tcx>, | |
45 | dest_layout: &'tcx ty::layout::Layout, | |
46 | target: mir::BasicBlock, | |
47 | ) -> EvalResult<'tcx>; | |
48 | ||
49 | /// Called for all binary operations except on float types. | |
50 | /// | |
51 | /// Returns `None` if the operation should be handled by the integer | |
52 | /// op code in order to share more code between machines | |
53 | /// | |
54 | /// Returns a (value, overflowed) pair if the operation succeeded | |
55 | fn try_ptr_op<'a>( | |
56 | ecx: &EvalContext<'a, 'tcx, Self>, | |
57 | bin_op: mir::BinOp, | |
58 | left: PrimVal, | |
59 | left_ty: ty::Ty<'tcx>, | |
60 | right: PrimVal, | |
61 | right_ty: ty::Ty<'tcx>, | |
62 | ) -> EvalResult<'tcx, Option<(PrimVal, bool)>>; | |
63 | ||
64 | /// Called when trying to mark machine defined `MemoryKinds` as static | |
65 | fn mark_static_initialized(m: Self::MemoryKinds) -> EvalResult<'tcx>; | |
66 | ||
67 | /// Heap allocations via the `box` keyword | |
68 | /// | |
69 | /// Returns a pointer to the allocated memory | |
70 | fn box_alloc<'a>( | |
71 | ecx: &mut EvalContext<'a, 'tcx, Self>, | |
72 | ty: ty::Ty<'tcx>, | |
73 | ) -> EvalResult<'tcx, PrimVal>; | |
74 | ||
75 | /// Called when trying to access a global declared with a `linkage` attribute | |
76 | fn global_item_with_linkage<'a>( | |
77 | ecx: &mut EvalContext<'a, 'tcx, Self>, | |
78 | instance: ty::Instance<'tcx>, | |
79 | mutability: Mutability, | |
80 | ) -> EvalResult<'tcx>; | |
81 | } |