mirror of
https://github.com/rust-lang/rust.git
synced 2024-12-02 19:53:46 +00:00
Rollup merge of #84905 - RalfJung:copy, r=oli-obk
CTFE engine: rename copy → copy_intrinsic, move to intrinsics.rs The `copy` name is confusing for this function because we also have `copy_op` which is pretty different. I hope `copy_intrinsic` is clearer. Also `step.rs` should really just contain the main loop and opcode dispatch, so move this helper function to a more appropriate place. r? ``````@oli-obk``````
This commit is contained in:
commit
eec3ae3feb
@ -323,7 +323,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||||||
self.write_scalar(result, dest)?;
|
self.write_scalar(result, dest)?;
|
||||||
}
|
}
|
||||||
sym::copy => {
|
sym::copy => {
|
||||||
self.copy(&args[0], &args[1], &args[2], /*nonoverlapping*/ false)?;
|
self.copy_intrinsic(&args[0], &args[1], &args[2], /*nonoverlapping*/ false)?;
|
||||||
}
|
}
|
||||||
sym::offset => {
|
sym::offset => {
|
||||||
let ptr = self.read_scalar(&args[0])?.check_init()?;
|
let ptr = self.read_scalar(&args[0])?.check_init()?;
|
||||||
@ -530,4 +530,36 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||||||
)?;
|
)?;
|
||||||
Ok(offset_ptr)
|
Ok(offset_ptr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Copy `count*size_of::<T>()` many bytes from `*src` to `*dst`.
|
||||||
|
pub(crate) fn copy_intrinsic(
|
||||||
|
&mut self,
|
||||||
|
src: &OpTy<'tcx, <M as Machine<'mir, 'tcx>>::PointerTag>,
|
||||||
|
dst: &OpTy<'tcx, <M as Machine<'mir, 'tcx>>::PointerTag>,
|
||||||
|
count: &OpTy<'tcx, <M as Machine<'mir, 'tcx>>::PointerTag>,
|
||||||
|
nonoverlapping: bool,
|
||||||
|
) -> InterpResult<'tcx> {
|
||||||
|
let count = self.read_scalar(&count)?.to_machine_usize(self)?;
|
||||||
|
let layout = self.layout_of(src.layout.ty.builtin_deref(true).unwrap().ty)?;
|
||||||
|
let (size, align) = (layout.size, layout.align.abi);
|
||||||
|
let size = size.checked_mul(count, self).ok_or_else(|| {
|
||||||
|
err_ub_format!(
|
||||||
|
"overflow computing total size of `{}`",
|
||||||
|
if nonoverlapping { "copy_nonoverlapping" } else { "copy" }
|
||||||
|
)
|
||||||
|
})?;
|
||||||
|
|
||||||
|
// Make sure we check both pointers for an access of the total size and aligment,
|
||||||
|
// *even if* the total size is 0.
|
||||||
|
let src =
|
||||||
|
self.memory.check_ptr_access(self.read_scalar(&src)?.check_init()?, size, align)?;
|
||||||
|
|
||||||
|
let dst =
|
||||||
|
self.memory.check_ptr_access(self.read_scalar(&dst)?.check_init()?, size, align)?;
|
||||||
|
|
||||||
|
if let (Some(src), Some(dst)) = (src, dst) {
|
||||||
|
self.memory.copy(src, dst, size, nonoverlapping)?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
//!
|
//!
|
||||||
//! The main entry point is the `step` method.
|
//! The main entry point is the `step` method.
|
||||||
|
|
||||||
use crate::interpret::OpTy;
|
|
||||||
use rustc_middle::mir;
|
use rustc_middle::mir;
|
||||||
use rustc_middle::mir::interpret::{InterpResult, Scalar};
|
use rustc_middle::mir::interpret::{InterpResult, Scalar};
|
||||||
use rustc_target::abi::LayoutOf;
|
use rustc_target::abi::LayoutOf;
|
||||||
@ -119,7 +118,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||||||
let src = self.eval_operand(src, None)?;
|
let src = self.eval_operand(src, None)?;
|
||||||
let dst = self.eval_operand(dst, None)?;
|
let dst = self.eval_operand(dst, None)?;
|
||||||
let count = self.eval_operand(count, None)?;
|
let count = self.eval_operand(count, None)?;
|
||||||
self.copy(&src, &dst, &count, /* nonoverlapping */ true)?;
|
self.copy_intrinsic(&src, &dst, &count, /* nonoverlapping */ true)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Statements we do not track.
|
// Statements we do not track.
|
||||||
@ -149,37 +148,6 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn copy(
|
|
||||||
&mut self,
|
|
||||||
src: &OpTy<'tcx, <M as Machine<'mir, 'tcx>>::PointerTag>,
|
|
||||||
dst: &OpTy<'tcx, <M as Machine<'mir, 'tcx>>::PointerTag>,
|
|
||||||
count: &OpTy<'tcx, <M as Machine<'mir, 'tcx>>::PointerTag>,
|
|
||||||
nonoverlapping: bool,
|
|
||||||
) -> InterpResult<'tcx> {
|
|
||||||
let count = self.read_scalar(&count)?.to_machine_usize(self)?;
|
|
||||||
let layout = self.layout_of(src.layout.ty.builtin_deref(true).unwrap().ty)?;
|
|
||||||
let (size, align) = (layout.size, layout.align.abi);
|
|
||||||
let size = size.checked_mul(count, self).ok_or_else(|| {
|
|
||||||
err_ub_format!(
|
|
||||||
"overflow computing total size of `{}`",
|
|
||||||
if nonoverlapping { "copy_nonoverlapping" } else { "copy" }
|
|
||||||
)
|
|
||||||
})?;
|
|
||||||
|
|
||||||
// Make sure we check both pointers for an access of the total size and aligment,
|
|
||||||
// *even if* the total size is 0.
|
|
||||||
let src =
|
|
||||||
self.memory.check_ptr_access(self.read_scalar(&src)?.check_init()?, size, align)?;
|
|
||||||
|
|
||||||
let dst =
|
|
||||||
self.memory.check_ptr_access(self.read_scalar(&dst)?.check_init()?, size, align)?;
|
|
||||||
|
|
||||||
if let (Some(src), Some(dst)) = (src, dst) {
|
|
||||||
self.memory.copy(src, dst, size, nonoverlapping)?;
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Evaluate an assignment statement.
|
/// Evaluate an assignment statement.
|
||||||
///
|
///
|
||||||
/// There is no separate `eval_rvalue` function. Instead, the code for handling each rvalue
|
/// There is no separate `eval_rvalue` function. Instead, the code for handling each rvalue
|
||||||
|
Loading…
Reference in New Issue
Block a user