2017-07-21 17:25:30 +02:00
|
|
|
//! This module contains everything needed to instantiate an interpreter.
|
|
|
|
//! This separation exists to ensure that no fancy miri features like
|
|
|
|
//! interpreting common C functions leak into CTFE.
|
|
|
|
|
2017-08-24 14:41:49 +02:00
|
|
|
use super::{EvalResult, EvalContext, Lvalue, PrimVal, ValTy};
|
2017-07-21 17:25:30 +02:00
|
|
|
|
|
|
|
use rustc::{mir, ty};
|
2017-07-28 09:52:19 +02:00
|
|
|
use syntax::codemap::Span;
|
2017-07-21 17:25:30 +02:00
|
|
|
|
|
|
|
/// Methods of this trait signifies a point where CTFE evaluation would fail
|
|
|
|
/// and some use case dependent behaviour can instead be applied
|
|
|
|
pub trait Machine<'tcx>: Sized {
|
|
|
|
/// Additional data that can be accessed via the EvalContext
|
|
|
|
type Data;
|
|
|
|
|
|
|
|
/// Additional data that can be accessed via the Memory
|
|
|
|
type MemoryData;
|
|
|
|
|
2017-07-28 16:48:43 +02:00
|
|
|
/// Additional memory kinds a machine wishes to distinguish from the builtin ones
|
|
|
|
type MemoryKinds: ::std::fmt::Debug + PartialEq + Copy + Clone;
|
|
|
|
|
2017-07-28 09:52:19 +02:00
|
|
|
/// Entry point to all function calls.
|
|
|
|
///
|
|
|
|
/// Returns Ok(true) when the function was handled completely
|
2017-07-28 10:16:19 +02:00
|
|
|
/// e.g. due to missing mir
|
2017-07-28 09:52:19 +02:00
|
|
|
///
|
|
|
|
/// Returns Ok(false) if a new stack frame was pushed
|
|
|
|
fn eval_fn_call<'a>(
|
2017-07-21 17:25:30 +02:00
|
|
|
ecx: &mut EvalContext<'a, 'tcx, Self>,
|
|
|
|
instance: ty::Instance<'tcx>,
|
2017-08-08 14:22:11 +02:00
|
|
|
destination: Option<(Lvalue, mir::BasicBlock)>,
|
2017-08-24 14:41:49 +02:00
|
|
|
args: &[ValTy<'tcx>],
|
2017-07-28 09:52:19 +02:00
|
|
|
span: Span,
|
2017-07-21 17:25:30 +02:00
|
|
|
sig: ty::FnSig<'tcx>,
|
2017-07-28 09:52:19 +02:00
|
|
|
) -> EvalResult<'tcx, bool>;
|
2017-07-25 11:32:48 +02:00
|
|
|
|
2017-07-28 13:08:27 +02:00
|
|
|
/// directly process an intrinsic without pushing a stack frame.
|
|
|
|
fn call_intrinsic<'a>(
|
|
|
|
ecx: &mut EvalContext<'a, 'tcx, Self>,
|
|
|
|
instance: ty::Instance<'tcx>,
|
2017-08-24 14:41:49 +02:00
|
|
|
args: &[ValTy<'tcx>],
|
2017-08-08 14:22:11 +02:00
|
|
|
dest: Lvalue,
|
2017-07-28 13:08:27 +02:00
|
|
|
dest_ty: ty::Ty<'tcx>,
|
|
|
|
dest_layout: &'tcx ty::layout::Layout,
|
|
|
|
target: mir::BasicBlock,
|
|
|
|
) -> EvalResult<'tcx>;
|
|
|
|
|
2017-08-01 11:11:57 +02:00
|
|
|
/// Called for all binary operations except on float types.
|
2017-07-25 11:32:48 +02:00
|
|
|
///
|
|
|
|
/// Returns `None` if the operation should be handled by the integer
|
2017-08-01 11:11:57 +02:00
|
|
|
/// op code in order to share more code between machines
|
2017-07-25 11:32:48 +02:00
|
|
|
///
|
2017-08-01 11:11:57 +02:00
|
|
|
/// Returns a (value, overflowed) pair if the operation succeeded
|
|
|
|
fn try_ptr_op<'a>(
|
2017-07-25 11:32:48 +02:00
|
|
|
ecx: &EvalContext<'a, 'tcx, Self>,
|
|
|
|
bin_op: mir::BinOp,
|
|
|
|
left: PrimVal,
|
|
|
|
left_ty: ty::Ty<'tcx>,
|
|
|
|
right: PrimVal,
|
|
|
|
right_ty: ty::Ty<'tcx>,
|
|
|
|
) -> EvalResult<'tcx, Option<(PrimVal, bool)>>;
|
2017-07-28 16:48:43 +02:00
|
|
|
|
|
|
|
/// Called when trying to mark machine defined `MemoryKinds` as static
|
|
|
|
fn mark_static_initialized(m: Self::MemoryKinds) -> EvalResult<'tcx>;
|
|
|
|
|
|
|
|
/// Heap allocations via the `box` keyword
|
|
|
|
///
|
|
|
|
/// Returns a pointer to the allocated memory
|
|
|
|
fn box_alloc<'a>(
|
|
|
|
ecx: &mut EvalContext<'a, 'tcx, Self>,
|
|
|
|
ty: ty::Ty<'tcx>,
|
|
|
|
) -> EvalResult<'tcx, PrimVal>;
|
2017-07-21 17:25:30 +02:00
|
|
|
}
|