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.
|
|
|
|
|
2018-06-21 21:40:14 -07:00
|
|
|
use std::hash::Hash;
|
|
|
|
|
2018-05-21 00:37:44 +02:00
|
|
|
use rustc::mir::interpret::{AllocId, EvalResult, Scalar, Pointer, AccessKind, GlobalId};
|
2018-08-13 16:14:22 +02:00
|
|
|
use super::{EvalContext, PlaceTy, OpTy, Memory};
|
2017-07-21 17:25:30 +02:00
|
|
|
|
2017-12-12 17:14:49 +01:00
|
|
|
use rustc::mir;
|
2018-08-13 16:14:22 +02:00
|
|
|
use rustc::ty::{self, layout::TyLayout};
|
2018-05-19 16:37:29 +02:00
|
|
|
use rustc::ty::layout::Size;
|
2018-08-18 12:14:03 +02:00
|
|
|
use syntax::source_map::Span;
|
2017-09-15 13:02:33 +02:00
|
|
|
use syntax::ast::Mutability;
|
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
|
2018-07-04 13:05:43 -07:00
|
|
|
pub trait Machine<'mir, 'tcx>: Clone + Eq + Hash {
|
2017-07-21 17:25:30 +02:00
|
|
|
/// Additional data that can be accessed via the Memory
|
2018-06-21 21:40:14 -07:00
|
|
|
type MemoryData: Clone + Eq + Hash;
|
2017-07-21 17:25:30 +02:00
|
|
|
|
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>(
|
2018-01-16 09:31:48 +01:00
|
|
|
ecx: &mut EvalContext<'a, 'mir, 'tcx, Self>,
|
2017-07-21 17:25:30 +02:00
|
|
|
instance: ty::Instance<'tcx>,
|
2018-08-13 16:14:22 +02:00
|
|
|
destination: Option<(PlaceTy<'tcx>, mir::BasicBlock)>,
|
|
|
|
args: &[OpTy<'tcx>],
|
2017-07-28 09:52:19 +02:00
|
|
|
span: Span,
|
|
|
|
) -> 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>(
|
2018-01-16 09:31:48 +01:00
|
|
|
ecx: &mut EvalContext<'a, 'mir, 'tcx, Self>,
|
2017-07-28 13:08:27 +02:00
|
|
|
instance: ty::Instance<'tcx>,
|
2018-08-13 16:14:22 +02:00
|
|
|
args: &[OpTy<'tcx>],
|
|
|
|
dest: PlaceTy<'tcx>,
|
2017-07-28 13:08:27 +02:00
|
|
|
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>(
|
2018-01-16 09:31:48 +01:00
|
|
|
ecx: &EvalContext<'a, 'mir, 'tcx, Self>,
|
2017-07-25 11:32:48 +02:00
|
|
|
bin_op: mir::BinOp,
|
2018-05-20 23:43:16 +02:00
|
|
|
left: Scalar,
|
2018-08-13 16:14:22 +02:00
|
|
|
left_layout: TyLayout<'tcx>,
|
2018-05-20 23:43:16 +02:00
|
|
|
right: Scalar,
|
2018-08-13 16:14:22 +02:00
|
|
|
right_layout: TyLayout<'tcx>,
|
2018-05-20 23:43:16 +02:00
|
|
|
) -> EvalResult<'tcx, Option<(Scalar, bool)>>;
|
2017-07-28 16:48:43 +02:00
|
|
|
|
|
|
|
/// Called when trying to mark machine defined `MemoryKinds` as static
|
2018-01-16 09:31:48 +01:00
|
|
|
fn mark_static_initialized<'a>(
|
|
|
|
_mem: &mut Memory<'a, 'mir, 'tcx, Self>,
|
|
|
|
_id: AllocId,
|
|
|
|
_mutability: Mutability,
|
|
|
|
) -> EvalResult<'tcx, bool>;
|
2017-07-28 16:48:43 +02:00
|
|
|
|
2018-01-25 08:06:53 +01:00
|
|
|
/// Called when requiring a pointer to a static. Non const eval can
|
|
|
|
/// create a mutable memory location for `static mut`
|
|
|
|
fn init_static<'a>(
|
|
|
|
ecx: &mut EvalContext<'a, 'mir, 'tcx, Self>,
|
|
|
|
cid: GlobalId<'tcx>,
|
|
|
|
) -> EvalResult<'tcx, AllocId>;
|
|
|
|
|
2017-07-28 16:48:43 +02:00
|
|
|
/// Heap allocations via the `box` keyword
|
|
|
|
///
|
|
|
|
/// Returns a pointer to the allocated memory
|
|
|
|
fn box_alloc<'a>(
|
2018-01-16 09:31:48 +01:00
|
|
|
ecx: &mut EvalContext<'a, 'mir, 'tcx, Self>,
|
2018-08-13 16:14:22 +02:00
|
|
|
dest: PlaceTy<'tcx>,
|
2017-09-25 15:55:21 +02:00
|
|
|
) -> EvalResult<'tcx>;
|
2017-09-15 13:02:33 +02:00
|
|
|
|
|
|
|
/// Called when trying to access a global declared with a `linkage` attribute
|
|
|
|
fn global_item_with_linkage<'a>(
|
2018-01-16 09:31:48 +01:00
|
|
|
ecx: &mut EvalContext<'a, 'mir, 'tcx, Self>,
|
2017-09-15 13:02:33 +02:00
|
|
|
instance: ty::Instance<'tcx>,
|
|
|
|
mutability: Mutability,
|
|
|
|
) -> EvalResult<'tcx>;
|
2017-12-14 11:36:28 +01:00
|
|
|
|
|
|
|
fn check_locks<'a>(
|
2018-01-16 09:31:48 +01:00
|
|
|
_mem: &Memory<'a, 'mir, 'tcx, Self>,
|
2018-05-21 00:37:44 +02:00
|
|
|
_ptr: Pointer,
|
2018-05-19 16:37:29 +02:00
|
|
|
_size: Size,
|
2017-12-14 11:36:28 +01:00
|
|
|
_access: AccessKind,
|
|
|
|
) -> EvalResult<'tcx> {
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
fn add_lock<'a>(
|
2018-01-16 09:31:48 +01:00
|
|
|
_mem: &mut Memory<'a, 'mir, 'tcx, Self>,
|
2018-01-05 05:12:38 +02:00
|
|
|
_id: AllocId,
|
2017-12-14 11:36:28 +01:00
|
|
|
) {}
|
|
|
|
|
|
|
|
fn free_lock<'a>(
|
2018-01-16 09:31:48 +01:00
|
|
|
_mem: &mut Memory<'a, 'mir, 'tcx, Self>,
|
2018-01-05 05:12:38 +02:00
|
|
|
_id: AllocId,
|
2017-12-14 11:36:28 +01:00
|
|
|
_len: u64,
|
|
|
|
) -> EvalResult<'tcx> {
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
fn end_region<'a>(
|
2018-01-16 09:31:48 +01:00
|
|
|
_ecx: &mut EvalContext<'a, 'mir, 'tcx, Self>,
|
2017-12-14 11:36:28 +01:00
|
|
|
_reg: Option<::rustc::middle::region::Scope>,
|
|
|
|
) -> EvalResult<'tcx> {
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
fn validation_op<'a>(
|
2018-01-16 09:31:48 +01:00
|
|
|
_ecx: &mut EvalContext<'a, 'mir, 'tcx, Self>,
|
2017-12-14 11:36:28 +01:00
|
|
|
_op: ::rustc::mir::ValidationOp,
|
|
|
|
_operand: &::rustc::mir::ValidationOperand<'tcx, ::rustc::mir::Place<'tcx>>,
|
|
|
|
) -> EvalResult<'tcx> {
|
|
|
|
Ok(())
|
|
|
|
}
|
2017-07-21 17:25:30 +02:00
|
|
|
}
|