12 impl<'mir, 'tcx> EvalContextExt<'mir, 'tcx> for crate::MiriEvalContext<'mir, 'tcx> {}
13 pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx> {
16 instance: ty::Instance<'tcx>,
17 args: &[OpTy<'tcx, Tag>],
18 dest: Option<PlaceTy<'tcx, Tag>>,
19 ret: Option<mir::BasicBlock>,
20 ) -> InterpResult<'tcx, Option<&'mir mir::Body<'tcx>>> {
21 let this = self.eval_context_mut();
23 "eval_fn_call: {:#?}, {:?}",
25 dest.map(|place| *place)
28 // First, run the common hooks also supported by CTFE.
29 if this.hook_fn(instance, args, dest)? {
30 this.goto_block(ret)?;
33 // There are some more lang items we want to hook that CTFE does not hook (yet).
34 if this.tcx.lang_items().align_offset_fn() == Some(instance.def.def_id()) {
35 let dest = dest.unwrap();
37 .align_offset(args[0], args[1])?
38 .unwrap_or_else(|| this.truncate(u128::max_value(), dest.layout));
39 this.write_scalar(Scalar::from_uint(n, dest.layout.size), dest)?;
40 this.goto_block(ret)?;
44 // Try to see if we can do something about foreign items.
45 if this.tcx.is_foreign_item(instance.def_id()) {
46 // An external function that we cannot find MIR for, but we can still run enough
47 // of them to make miri viable.
48 this.emulate_foreign_item(instance.def_id(), args, dest, ret)?;
49 // `goto_block` already handled.
53 // Otherwise, load the MIR.
54 Ok(Some(this.load_mir(instance.def, None)?))
59 ptr_op: OpTy<'tcx, Tag>,
60 align_op: OpTy<'tcx, Tag>,
61 ) -> InterpResult<'tcx, Option<u128>> {
62 let this = self.eval_context_mut();
64 let req_align = this.force_bits(
65 this.read_scalar(align_op)?.not_undef()?,
69 // FIXME: This should actually panic in the interpreted program
70 if !req_align.is_power_of_two() {
71 throw_unsup_format!("Required alignment should always be a power of two")
74 let ptr_scalar = this.read_scalar(ptr_op)?.not_undef()?;
76 if let Ok(ptr) = this.force_ptr(ptr_scalar) {
77 let cur_align = this.memory().get(ptr.alloc_id)?.align.bytes() as usize;
78 if cur_align >= req_align {
79 // if the allocation alignment is at least the required alignment we use the
80 // libcore implementation
82 (this.force_bits(ptr_scalar, this.pointer_size())? as *const i8)
83 .align_offset(req_align) as u128,
87 // If the allocation alignment is smaller than then required alignment or the pointer was
88 // actually an integer, we return `None`