Auto merge of #814 - RalfJung:shims, r=RalfJung
move find_fn (which is not specific to foreign items) out of foreign_item
This commit is contained in:
commit
10af3871c9
3 changed files with 48 additions and 41 deletions
|
|
@ -28,6 +28,7 @@ pub use rustc_mir::interpret::*;
|
|||
// Resolve ambiguity.
|
||||
pub use rustc_mir::interpret::{self, AllocMap, PlaceTy};
|
||||
|
||||
pub use crate::shims::{EvalContextExt as ShimsEvalContextExt};
|
||||
pub use crate::shims::foreign_items::EvalContextExt as ForeignItemsEvalContextExt;
|
||||
pub use crate::shims::intrinsics::EvalContextExt as IntrinsicsEvalContextExt;
|
||||
pub use crate::operator::EvalContextExt as OperatorEvalContextExt;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
use rustc::ty;
|
||||
use rustc::ty::layout::{Align, LayoutOf, Size};
|
||||
use rustc::hir::def_id::DefId;
|
||||
use rustc::mir;
|
||||
|
|
@ -11,46 +10,6 @@ use crate::*;
|
|||
|
||||
impl<'mir, 'tcx> EvalContextExt<'mir, 'tcx> for crate::MiriEvalContext<'mir, 'tcx> {}
|
||||
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx> {
|
||||
fn find_fn(
|
||||
&mut self,
|
||||
instance: ty::Instance<'tcx>,
|
||||
args: &[OpTy<'tcx, Tag>],
|
||||
dest: Option<PlaceTy<'tcx, Tag>>,
|
||||
ret: Option<mir::BasicBlock>,
|
||||
) -> InterpResult<'tcx, Option<&'mir mir::Body<'tcx>>> {
|
||||
let this = self.eval_context_mut();
|
||||
trace!("eval_fn_call: {:#?}, {:?}", instance, dest.map(|place| *place));
|
||||
|
||||
// First, run the common hooks also supported by CTFE.
|
||||
if this.hook_fn(instance, args, dest)? {
|
||||
this.goto_block(ret)?;
|
||||
return Ok(None);
|
||||
}
|
||||
// There are some more lang items we want to hook that CTFE does not hook (yet).
|
||||
if this.tcx.lang_items().align_offset_fn() == Some(instance.def.def_id()) {
|
||||
// FIXME: return a real value in case the target allocation has an
|
||||
// alignment bigger than the one requested.
|
||||
let n = u128::max_value();
|
||||
let dest = dest.unwrap();
|
||||
let n = this.truncate(n, dest.layout);
|
||||
this.write_scalar(Scalar::from_uint(n, dest.layout.size), dest)?;
|
||||
this.goto_block(ret)?;
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
// Try to see if we can do something about foreign items.
|
||||
if this.tcx.is_foreign_item(instance.def_id()) {
|
||||
// An external function that we cannot find MIR for, but we can still run enough
|
||||
// of them to make miri viable.
|
||||
this.emulate_foreign_item(instance.def_id(), args, dest, ret)?;
|
||||
// `goto_block` already handled.
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
// Otherwise, load the MIR.
|
||||
Ok(Some(this.load_mir(instance.def)?))
|
||||
}
|
||||
|
||||
/// Returns the minimum alignment for the target architecture.
|
||||
fn min_align(&self) -> Align {
|
||||
let this = self.eval_context_ref();
|
||||
|
|
|
|||
|
|
@ -1,2 +1,49 @@
|
|||
pub mod foreign_items;
|
||||
pub mod intrinsics;
|
||||
|
||||
use rustc::{ty, mir};
|
||||
|
||||
use crate::*;
|
||||
|
||||
impl<'mir, 'tcx> EvalContextExt<'mir, 'tcx> for crate::MiriEvalContext<'mir, 'tcx> {}
|
||||
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx> {
|
||||
fn find_fn(
|
||||
&mut self,
|
||||
instance: ty::Instance<'tcx>,
|
||||
args: &[OpTy<'tcx, Tag>],
|
||||
dest: Option<PlaceTy<'tcx, Tag>>,
|
||||
ret: Option<mir::BasicBlock>,
|
||||
) -> InterpResult<'tcx, Option<&'mir mir::Body<'tcx>>> {
|
||||
let this = self.eval_context_mut();
|
||||
trace!("eval_fn_call: {:#?}, {:?}", instance, dest.map(|place| *place));
|
||||
|
||||
// First, run the common hooks also supported by CTFE.
|
||||
if this.hook_fn(instance, args, dest)? {
|
||||
this.goto_block(ret)?;
|
||||
return Ok(None);
|
||||
}
|
||||
// There are some more lang items we want to hook that CTFE does not hook (yet).
|
||||
if this.tcx.lang_items().align_offset_fn() == Some(instance.def.def_id()) {
|
||||
// FIXME: return a real value in case the target allocation has an
|
||||
// alignment bigger than the one requested.
|
||||
let n = u128::max_value();
|
||||
let dest = dest.unwrap();
|
||||
let n = this.truncate(n, dest.layout);
|
||||
this.write_scalar(Scalar::from_uint(n, dest.layout.size), dest)?;
|
||||
this.goto_block(ret)?;
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
// Try to see if we can do something about foreign items.
|
||||
if this.tcx.is_foreign_item(instance.def_id()) {
|
||||
// An external function that we cannot find MIR for, but we can still run enough
|
||||
// of them to make miri viable.
|
||||
this.emulate_foreign_item(instance.def_id(), args, dest, ret)?;
|
||||
// `goto_block` already handled.
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
// Otherwise, load the MIR.
|
||||
Ok(Some(this.load_mir(instance.def)?))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue