2017-07-21 10:25:30 -05: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.
|
|
|
|
|
|
|
|
use super::{
|
|
|
|
EvalResult,
|
|
|
|
EvalContext,
|
|
|
|
Lvalue,
|
2017-07-25 04:32:48 -05:00
|
|
|
PrimVal
|
2017-07-21 10:25:30 -05:00
|
|
|
};
|
|
|
|
|
|
|
|
use rustc::{mir, ty};
|
2017-07-28 02:52:19 -05:00
|
|
|
use syntax::codemap::Span;
|
2017-07-21 10:25:30 -05: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 02:52:19 -05:00
|
|
|
/// Entry point to all function calls.
|
|
|
|
///
|
|
|
|
/// Returns Ok(true) when the function was handled completely
|
2017-07-28 03:16:19 -05:00
|
|
|
/// e.g. due to missing mir
|
2017-07-28 02:52:19 -05:00
|
|
|
///
|
|
|
|
/// Returns Ok(false) if a new stack frame was pushed
|
|
|
|
fn eval_fn_call<'a>(
|
2017-07-21 10:25:30 -05:00
|
|
|
ecx: &mut EvalContext<'a, 'tcx, Self>,
|
|
|
|
instance: ty::Instance<'tcx>,
|
|
|
|
destination: Option<(Lvalue<'tcx>, mir::BasicBlock)>,
|
|
|
|
arg_operands: &[mir::Operand<'tcx>],
|
2017-07-28 02:52:19 -05:00
|
|
|
span: Span,
|
2017-07-21 10:25:30 -05:00
|
|
|
sig: ty::FnSig<'tcx>,
|
2017-07-28 02:52:19 -05:00
|
|
|
) -> EvalResult<'tcx, bool>;
|
2017-07-25 04:32:48 -05:00
|
|
|
|
2017-07-28 06:08:27 -05:00
|
|
|
/// directly process an intrinsic without pushing a stack frame.
|
|
|
|
fn call_intrinsic<'a>(
|
|
|
|
ecx: &mut EvalContext<'a, 'tcx, Self>,
|
|
|
|
instance: ty::Instance<'tcx>,
|
|
|
|
args: &[mir::Operand<'tcx>],
|
|
|
|
dest: Lvalue<'tcx>,
|
|
|
|
dest_ty: ty::Ty<'tcx>,
|
|
|
|
dest_layout: &'tcx ty::layout::Layout,
|
|
|
|
target: mir::BasicBlock,
|
|
|
|
) -> EvalResult<'tcx>;
|
|
|
|
|
2017-07-25 04:32:48 -05:00
|
|
|
/// Called when operating on the value of pointers.
|
|
|
|
///
|
|
|
|
/// Returns `None` if the operation should be handled by the integer
|
|
|
|
/// op code
|
|
|
|
///
|
|
|
|
/// Returns a (value, overflowed) pair otherwise
|
|
|
|
fn ptr_op<'a>(
|
|
|
|
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-21 10:25:30 -05:00
|
|
|
}
|
|
|
|
|