adjust for goto_block refactoring

This commit is contained in:
Ralf Jung 2019-11-25 22:48:31 +01:00
parent 91cec06f4c
commit 824328c6d5
6 changed files with 37 additions and 48 deletions

View File

@ -186,11 +186,10 @@ fn find_fn(
ecx: &mut InterpCx<'mir, 'tcx, Self>,
instance: ty::Instance<'tcx>,
args: &[OpTy<'tcx, Tag>],
dest: Option<PlaceTy<'tcx, Tag>>,
ret: Option<mir::BasicBlock>,
ret: Option<(PlaceTy<'tcx, Tag>, mir::BasicBlock)>,
unwind: Option<mir::BasicBlock>,
) -> InterpResult<'tcx, Option<&'mir mir::Body<'tcx>>> {
ecx.find_fn(instance, args, dest, ret, unwind)
ecx.find_fn(instance, args, ret, unwind)
}
#[inline(always)]
@ -198,10 +197,10 @@ fn call_extra_fn(
ecx: &mut InterpCx<'mir, 'tcx, Self>,
fn_val: Dlsym,
args: &[OpTy<'tcx, Tag>],
dest: Option<PlaceTy<'tcx, Tag>>,
ret: Option<mir::BasicBlock>,
ret: Option<(PlaceTy<'tcx, Tag>, mir::BasicBlock)>,
_unwind: Option<mir::BasicBlock>,
) -> InterpResult<'tcx> {
ecx.call_dlsym(fn_val, args, dest, ret)
ecx.call_dlsym(fn_val, args, ret)
}
#[inline(always)]
@ -210,11 +209,10 @@ fn call_intrinsic(
span: Span,
instance: ty::Instance<'tcx>,
args: &[OpTy<'tcx, Tag>],
dest: Option<PlaceTy<'tcx, Tag>>,
ret: Option<mir::BasicBlock>,
ret: Option<(PlaceTy<'tcx, Tag>, mir::BasicBlock)>,
unwind: Option<mir::BasicBlock>,
) -> InterpResult<'tcx> {
ecx.call_intrinsic(span, instance, args, dest, ret, unwind)
ecx.call_intrinsic(span, instance, args, ret, unwind)
}
#[inline(always)]

View File

@ -27,15 +27,12 @@ fn call_dlsym(
&mut self,
dlsym: Dlsym,
args: &[OpTy<'tcx, Tag>],
dest: Option<PlaceTy<'tcx, Tag>>,
ret: Option<mir::BasicBlock>,
ret: Option<(PlaceTy<'tcx, Tag>, mir::BasicBlock)>,
) -> InterpResult<'tcx> {
use self::Dlsym::*;
let this = self.eval_context_mut();
let dest = dest.expect("we don't support any diverging dlsym");
let ret = ret.expect("dest is `Some` but ret is `None`");
let (dest, ret) = ret.expect("we don't support any diverging dlsym");
match dlsym {
GetEntropy => {
@ -46,8 +43,8 @@ fn call_dlsym(
}
}
this.goto_block(Some(ret))?;
this.dump_place(*dest);
this.go_to_block(ret);
Ok(())
}
}

View File

@ -114,8 +114,7 @@ fn emulate_foreign_item(
&mut self,
def_id: DefId,
args: &[OpTy<'tcx, Tag>],
dest: Option<PlaceTy<'tcx, Tag>>,
ret: Option<mir::BasicBlock>,
ret: Option<(PlaceTy<'tcx, Tag>, mir::BasicBlock)>,
_unwind: Option<mir::BasicBlock>
) -> InterpResult<'tcx, Option<&'mir mir::Body<'tcx>>> {
let this = self.eval_context_mut();
@ -129,7 +128,7 @@ fn emulate_foreign_item(
let tcx = &{ this.tcx.tcx };
// First: functions that diverge.
match link_name {
let (dest, ret) = match link_name {
// Note that this matches calls to the *foreign* item `__rust_start_panic* -
// that is, calls to `extern "Rust" { fn __rust_start_panic(...) }`.
// We forward this to the underlying *implementation* in the panic runtime crate.
@ -154,15 +153,15 @@ fn emulate_foreign_item(
return Err(InterpError::Exit(code).into());
}
_ => {
if dest.is_none() {
if let Some(p) = ret {
p
} else {
throw_unsup_format!("can't call (diverging) foreign function: {}", link_name);
}
}
}
};
// Next: functions that assume a ret and dest.
let dest = dest.expect("we already checked for a dest");
let ret = ret.expect("dest is `Some` but ret is `None`");
// Next: functions that return.
match link_name {
"malloc" => {
let size = this.read_scalar(args[0])?.to_machine_usize(this)?;
@ -928,8 +927,8 @@ fn emulate_foreign_item(
_ => throw_unsup_format!("can't call foreign function: {}", link_name),
}
this.goto_block(Some(ret))?;
this.dump_place(*dest);
this.go_to_block(ret);
Ok(None)
}

View File

@ -16,12 +16,11 @@ fn call_intrinsic(
span: Span,
instance: ty::Instance<'tcx>,
args: &[OpTy<'tcx, Tag>],
dest: Option<PlaceTy<'tcx, Tag>>,
_ret: Option<mir::BasicBlock>,
ret: Option<(PlaceTy<'tcx, Tag>, mir::BasicBlock)>,
unwind: Option<mir::BasicBlock>
) -> InterpResult<'tcx> {
let this = self.eval_context_mut();
if this.emulate_intrinsic(span, instance, args, dest)? {
if this.emulate_intrinsic(span, instance, args, ret)? {
return Ok(());
}
let tcx = &{this.tcx.tcx};
@ -32,23 +31,21 @@ fn call_intrinsic(
// that might still hang around!
let intrinsic_name = &*tcx.item_name(instance.def_id()).as_str();
// Handle diverging intrinsics
match intrinsic_name {
// Handle diverging intrinsics.
let (dest, ret) = match intrinsic_name {
"abort" => {
// FIXME: Add a better way of indicating 'abnormal' termination,
// since this is not really an 'unsupported' behavior
throw_unsup_format!("the evaluated program aborted!");
}
"miri_start_panic" => return this.handle_miri_start_panic(args, unwind),
_ => {}
}
// Handle non-diverging intrinsics
// The intrinsic itself cannot diverge (otherwise, we would have handled it above),
// so if we got here without a return place that's UB (can happen e.g., for transmute returning `!`).
let dest = match dest {
Some(dest) => dest,
None => throw_ub!(Unreachable)
_ => {
if let Some(p) = ret {
p
} else {
throw_unsup_format!("unimplemented (diverging) intrinsic: {}", intrinsic_name);
}
}
};
match intrinsic_name {
@ -581,6 +578,8 @@ fn call_intrinsic(
name => throw_unsup_format!("unimplemented intrinsic: {}", name),
}
this.dump_place(*dest);
this.go_to_block(ret);
Ok(())
}
}

View File

@ -16,25 +16,24 @@ fn find_fn(
&mut self,
instance: ty::Instance<'tcx>,
args: &[OpTy<'tcx, Tag>],
dest: Option<PlaceTy<'tcx, Tag>>,
ret: Option<mir::BasicBlock>,
ret: Option<(PlaceTy<'tcx, Tag>, mir::BasicBlock)>,
unwind: 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)
ret.map(|p| *p.0)
);
// 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()) {
let dest = dest.unwrap();
let (dest, ret) = ret.unwrap();
let n = this
.align_offset(args[0], args[1])?
.unwrap_or_else(|| this.truncate(u128::max_value(), dest.layout));
this.write_scalar(Scalar::from_uint(n, dest.layout.size), dest)?;
this.goto_block(ret)?;
this.go_to_block(ret);
return Ok(None);
}
@ -46,7 +45,7 @@ fn find_fn(
// to run extra MIR), and Ok(Some(body)) if we found MIR to run for the
// foreign function
// Any needed call to `goto_block` will be performed by `emulate_foreign_item`.
return this.emulate_foreign_item(instance.def_id(), args, dest, ret, unwind);
return this.emulate_foreign_item(instance.def_id(), args, ret, unwind);
}
// Otherwise, load the MIR.

View File

@ -53,10 +53,7 @@ fn handle_miri_start_panic(
this.machine.panic_payload = Some(scalar);
// Jump to the unwind block to begin unwinding.
// We don't use `goto_block` as that is just meant for normal returns.
let next_frame = this.frame_mut();
next_frame.block = unwind;
next_frame.stmt = 0;
this.unwind_to_block(unwind);
return Ok(())
}