interpret: move nullary-op evaluation into operator.rs
This commit is contained in:
parent
83e9b93c90
commit
46896d6f66
@ -458,7 +458,7 @@ fn call_intrinsic(
|
|||||||
_unwind: mir::UnwindAction,
|
_unwind: mir::UnwindAction,
|
||||||
) -> InterpResult<'tcx, Option<ty::Instance<'tcx>>> {
|
) -> InterpResult<'tcx, Option<ty::Instance<'tcx>>> {
|
||||||
// Shared intrinsics.
|
// Shared intrinsics.
|
||||||
if ecx.emulate_intrinsic(instance, args, dest, target)? {
|
if ecx.eval_intrinsic(instance, args, dest, target)? {
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
}
|
}
|
||||||
let intrinsic_name = ecx.tcx.item_name(instance.def_id());
|
let intrinsic_name = ecx.tcx.item_name(instance.def_id());
|
||||||
|
@ -97,7 +97,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
|||||||
/// Returns `true` if emulation happened.
|
/// Returns `true` if emulation happened.
|
||||||
/// Here we implement the intrinsics that are common to all Miri instances; individual machines can add their own
|
/// Here we implement the intrinsics that are common to all Miri instances; individual machines can add their own
|
||||||
/// intrinsic handling.
|
/// intrinsic handling.
|
||||||
pub fn emulate_intrinsic(
|
pub fn eval_intrinsic(
|
||||||
&mut self,
|
&mut self,
|
||||||
instance: ty::Instance<'tcx>,
|
instance: ty::Instance<'tcx>,
|
||||||
args: &[OpTy<'tcx, M::Provenance>],
|
args: &[OpTy<'tcx, M::Provenance>],
|
||||||
@ -447,7 +447,7 @@ pub fn emulate_intrinsic(
|
|||||||
Ok(true)
|
Ok(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn emulate_nondiverging_intrinsic(
|
pub(super) fn eval_nondiverging_intrinsic(
|
||||||
&mut self,
|
&mut self,
|
||||||
intrinsic: &NonDivergingIntrinsic<'tcx>,
|
intrinsic: &NonDivergingIntrinsic<'tcx>,
|
||||||
) -> InterpResult<'tcx> {
|
) -> InterpResult<'tcx> {
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
use either::Either;
|
use either::Either;
|
||||||
use rustc_apfloat::{Float, FloatConvert};
|
use rustc_apfloat::{Float, FloatConvert};
|
||||||
use rustc_middle::mir::interpret::{InterpResult, Scalar};
|
use rustc_middle::mir::interpret::{InterpResult, Scalar};
|
||||||
|
use rustc_middle::mir::NullOp;
|
||||||
use rustc_middle::ty::layout::{LayoutOf, TyAndLayout};
|
use rustc_middle::ty::layout::{LayoutOf, TyAndLayout};
|
||||||
use rustc_middle::ty::{self, FloatTy, ScalarInt};
|
use rustc_middle::ty::{self, FloatTy, ScalarInt, Ty};
|
||||||
use rustc_middle::{bug, mir, span_bug};
|
use rustc_middle::{bug, mir, span_bug};
|
||||||
use rustc_span::symbol::sym;
|
use rustc_span::symbol::sym;
|
||||||
use tracing::trace;
|
use tracing::trace;
|
||||||
@ -480,4 +481,38 @@ pub fn unary_op(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn nullary_op(
|
||||||
|
&self,
|
||||||
|
null_op: NullOp<'tcx>,
|
||||||
|
arg_ty: Ty<'tcx>,
|
||||||
|
) -> InterpResult<'tcx, ImmTy<'tcx, M::Provenance>> {
|
||||||
|
use rustc_middle::mir::NullOp::*;
|
||||||
|
|
||||||
|
let layout = self.layout_of(arg_ty)?;
|
||||||
|
let usize_layout = || self.layout_of(self.tcx.types.usize).unwrap();
|
||||||
|
|
||||||
|
Ok(match null_op {
|
||||||
|
SizeOf => {
|
||||||
|
if !layout.abi.is_sized() {
|
||||||
|
span_bug!(self.cur_span(), "unsized type for `NullaryOp::SizeOf`");
|
||||||
|
}
|
||||||
|
let val = layout.size.bytes();
|
||||||
|
ImmTy::from_uint(val, usize_layout())
|
||||||
|
}
|
||||||
|
AlignOf => {
|
||||||
|
if !layout.abi.is_sized() {
|
||||||
|
span_bug!(self.cur_span(), "unsized type for `NullaryOp::AlignOf`");
|
||||||
|
}
|
||||||
|
let val = layout.align.abi.bytes();
|
||||||
|
ImmTy::from_uint(val, usize_layout())
|
||||||
|
}
|
||||||
|
OffsetOf(fields) => {
|
||||||
|
let val =
|
||||||
|
self.tcx.offset_of_subfield(self.param_env, layout, fields.iter()).bytes();
|
||||||
|
ImmTy::from_uint(val, usize_layout())
|
||||||
|
}
|
||||||
|
UbChecks => ImmTy::from_bool(self.tcx.sess.ub_checks(), *self.tcx),
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,8 +4,7 @@
|
|||||||
|
|
||||||
use either::Either;
|
use either::Either;
|
||||||
use rustc_index::IndexSlice;
|
use rustc_index::IndexSlice;
|
||||||
use rustc_middle::ty::layout::LayoutOf;
|
use rustc_middle::{bug, mir};
|
||||||
use rustc_middle::{bug, mir, span_bug};
|
|
||||||
use rustc_target::abi::{FieldIdx, FIRST_VARIANT};
|
use rustc_target::abi::{FieldIdx, FIRST_VARIANT};
|
||||||
use tracing::{info, instrument, trace};
|
use tracing::{info, instrument, trace};
|
||||||
|
|
||||||
@ -94,7 +93,7 @@ pub fn statement(&mut self, stmt: &mir::Statement<'tcx>) -> InterpResult<'tcx> {
|
|||||||
M::retag_place_contents(self, *kind, &dest)?;
|
M::retag_place_contents(self, *kind, &dest)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Intrinsic(box intrinsic) => self.emulate_nondiverging_intrinsic(intrinsic)?,
|
Intrinsic(box intrinsic) => self.eval_nondiverging_intrinsic(intrinsic)?,
|
||||||
|
|
||||||
// Evaluate the place expression, without reading from it.
|
// Evaluate the place expression, without reading from it.
|
||||||
PlaceMention(box place) => {
|
PlaceMention(box place) => {
|
||||||
@ -179,6 +178,12 @@ pub fn eval_rvalue_into_place(
|
|||||||
self.write_immediate(*result, &dest)?;
|
self.write_immediate(*result, &dest)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NullaryOp(null_op, ty) => {
|
||||||
|
let ty = self.instantiate_from_current_frame_and_normalize_erasing_regions(ty)?;
|
||||||
|
let val = self.nullary_op(null_op, ty)?;
|
||||||
|
self.write_immediate(*val, &dest)?;
|
||||||
|
}
|
||||||
|
|
||||||
Aggregate(box ref kind, ref operands) => {
|
Aggregate(box ref kind, ref operands) => {
|
||||||
self.write_aggregate(kind, operands, &dest)?;
|
self.write_aggregate(kind, operands, &dest)?;
|
||||||
}
|
}
|
||||||
@ -230,38 +235,6 @@ pub fn eval_rvalue_into_place(
|
|||||||
self.write_immediate(*val, &dest)?;
|
self.write_immediate(*val, &dest)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
NullaryOp(ref null_op, ty) => {
|
|
||||||
let ty = self.instantiate_from_current_frame_and_normalize_erasing_regions(ty)?;
|
|
||||||
let layout = self.layout_of(ty)?;
|
|
||||||
if let mir::NullOp::SizeOf | mir::NullOp::AlignOf = null_op
|
|
||||||
&& layout.is_unsized()
|
|
||||||
{
|
|
||||||
span_bug!(
|
|
||||||
self.frame().current_span(),
|
|
||||||
"{null_op:?} MIR operator called for unsized type {ty}",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
let val = match null_op {
|
|
||||||
mir::NullOp::SizeOf => {
|
|
||||||
let val = layout.size.bytes();
|
|
||||||
Scalar::from_target_usize(val, self)
|
|
||||||
}
|
|
||||||
mir::NullOp::AlignOf => {
|
|
||||||
let val = layout.align.abi.bytes();
|
|
||||||
Scalar::from_target_usize(val, self)
|
|
||||||
}
|
|
||||||
mir::NullOp::OffsetOf(fields) => {
|
|
||||||
let val = self
|
|
||||||
.tcx
|
|
||||||
.offset_of_subfield(self.param_env, layout, fields.iter())
|
|
||||||
.bytes();
|
|
||||||
Scalar::from_target_usize(val, self)
|
|
||||||
}
|
|
||||||
mir::NullOp::UbChecks => Scalar::from_bool(self.tcx.sess.ub_checks()),
|
|
||||||
};
|
|
||||||
self.write_scalar(val, &dest)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
ShallowInitBox(ref operand, _) => {
|
ShallowInitBox(ref operand, _) => {
|
||||||
let src = self.eval_operand(operand, None)?;
|
let src = self.eval_operand(operand, None)?;
|
||||||
let v = self.read_immediate(&src)?;
|
let v = self.read_immediate(&src)?;
|
||||||
|
@ -33,7 +33,7 @@ fn call_intrinsic(
|
|||||||
let this = self.eval_context_mut();
|
let this = self.eval_context_mut();
|
||||||
|
|
||||||
// See if the core engine can handle this intrinsic.
|
// See if the core engine can handle this intrinsic.
|
||||||
if this.emulate_intrinsic(instance, args, dest, ret)? {
|
if this.eval_intrinsic(instance, args, dest, ret)? {
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
}
|
}
|
||||||
let intrinsic_name = this.tcx.item_name(instance.def_id());
|
let intrinsic_name = this.tcx.item_name(instance.def_id());
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
error: internal compiler error: compiler/rustc_const_eval/src/interpret/step.rs:LL:CC: SizeOf MIR operator called for unsized type dyn Debug
|
error: internal compiler error: compiler/rustc_const_eval/src/interpret/operator.rs:LL:CC: unsized type for `NullaryOp::SizeOf`
|
||||||
--> $SRC_DIR/core/src/mem/mod.rs:LL:COL
|
--> $SRC_DIR/core/src/mem/mod.rs:LL:COL
|
||||||
|
|
||||||
Box<dyn Any>
|
Box<dyn Any>
|
||||||
|
Loading…
Reference in New Issue
Block a user