support creating mutable allocations from byte slices
This commit is contained in:
parent
c3005e85da
commit
585141b219
8 changed files with 30 additions and 15 deletions
|
@ -100,7 +100,11 @@ impl AllocRange {
|
||||||
// The constructors are all without extra; the extra gets added by a machine hook later.
|
// The constructors are all without extra; the extra gets added by a machine hook later.
|
||||||
impl<Tag> Allocation<Tag> {
|
impl<Tag> Allocation<Tag> {
|
||||||
/// Creates a read-only allocation initialized by the given bytes
|
/// Creates a read-only allocation initialized by the given bytes
|
||||||
pub fn from_bytes<'a>(slice: impl Into<Cow<'a, [u8]>>, align: Align) -> Self {
|
pub fn from_bytes<'a>(
|
||||||
|
slice: impl Into<Cow<'a, [u8]>>,
|
||||||
|
align: Align,
|
||||||
|
mutability: Mutability,
|
||||||
|
) -> Self {
|
||||||
let bytes = slice.into().into_owned();
|
let bytes = slice.into().into_owned();
|
||||||
let size = Size::from_bytes(bytes.len());
|
let size = Size::from_bytes(bytes.len());
|
||||||
Self {
|
Self {
|
||||||
|
@ -108,13 +112,13 @@ impl<Tag> Allocation<Tag> {
|
||||||
relocations: Relocations::new(),
|
relocations: Relocations::new(),
|
||||||
init_mask: InitMask::new(size, true),
|
init_mask: InitMask::new(size, true),
|
||||||
align,
|
align,
|
||||||
mutability: Mutability::Not,
|
mutability,
|
||||||
extra: (),
|
extra: (),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_byte_aligned_bytes<'a>(slice: impl Into<Cow<'a, [u8]>>) -> Self {
|
pub fn from_bytes_byte_aligned_immutable<'a>(slice: impl Into<Cow<'a, [u8]>>) -> Self {
|
||||||
Allocation::from_bytes(slice, Align::ONE)
|
Allocation::from_bytes(slice, Align::ONE, Mutability::Not)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn uninit(size: Size, align: Align) -> Self {
|
pub fn uninit(size: Size, align: Align) -> Self {
|
||||||
|
|
|
@ -1072,7 +1072,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||||
/// Allocates a read-only byte or string literal for `mir::interpret`.
|
/// Allocates a read-only byte or string literal for `mir::interpret`.
|
||||||
pub fn allocate_bytes(self, bytes: &[u8]) -> interpret::AllocId {
|
pub fn allocate_bytes(self, bytes: &[u8]) -> interpret::AllocId {
|
||||||
// Create an allocation that just contains these bytes.
|
// Create an allocation that just contains these bytes.
|
||||||
let alloc = interpret::Allocation::from_byte_aligned_bytes(bytes);
|
let alloc = interpret::Allocation::from_bytes_byte_aligned_immutable(bytes);
|
||||||
let alloc = self.intern_const_alloc(alloc);
|
let alloc = self.intern_const_alloc(alloc);
|
||||||
self.create_memory_alloc(alloc)
|
self.create_memory_alloc(alloc)
|
||||||
}
|
}
|
||||||
|
|
|
@ -169,8 +169,9 @@ pub(super) fn op_to_const<'tcx>(
|
||||||
(ecx.tcx.global_alloc(ptr.alloc_id).unwrap_memory(), ptr.offset.bytes())
|
(ecx.tcx.global_alloc(ptr.alloc_id).unwrap_memory(), ptr.offset.bytes())
|
||||||
}
|
}
|
||||||
Scalar::Int { .. } => (
|
Scalar::Int { .. } => (
|
||||||
ecx.tcx
|
ecx.tcx.intern_const_alloc(Allocation::from_bytes_byte_aligned_immutable(
|
||||||
.intern_const_alloc(Allocation::from_byte_aligned_bytes(b"" as &[u8])),
|
b"" as &[u8],
|
||||||
|
)),
|
||||||
0,
|
0,
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
|
|
||||||
|
use rustc_ast::Mutability;
|
||||||
use rustc_hir::lang_items::LangItem;
|
use rustc_hir::lang_items::LangItem;
|
||||||
use rustc_middle::mir::TerminatorKind;
|
use rustc_middle::mir::TerminatorKind;
|
||||||
use rustc_middle::ty::subst::Subst;
|
use rustc_middle::ty::subst::Subst;
|
||||||
|
@ -79,7 +80,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||||
line: u32,
|
line: u32,
|
||||||
col: u32,
|
col: u32,
|
||||||
) -> MPlaceTy<'tcx, M::PointerTag> {
|
) -> MPlaceTy<'tcx, M::PointerTag> {
|
||||||
let file = self.allocate_str(&filename.as_str(), MemoryKind::CallerLocation);
|
let file =
|
||||||
|
self.allocate_str(&filename.as_str(), MemoryKind::CallerLocation, Mutability::Not);
|
||||||
let line = Scalar::from_u32(line);
|
let line = Scalar::from_u32(line);
|
||||||
let col = Scalar::from_u32(col);
|
let col = Scalar::from_u32(col);
|
||||||
|
|
||||||
|
|
|
@ -197,6 +197,6 @@ impl Write for AbsolutePathPrinter<'_> {
|
||||||
/// Directly returns an `Allocation` containing an absolute path representation of the given type.
|
/// Directly returns an `Allocation` containing an absolute path representation of the given type.
|
||||||
crate fn alloc_type_name<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> &'tcx Allocation {
|
crate fn alloc_type_name<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> &'tcx Allocation {
|
||||||
let path = AbsolutePathPrinter { tcx, path: String::new() }.print_type(ty).unwrap().path;
|
let path = AbsolutePathPrinter { tcx, path: String::new() }.print_type(ty).unwrap().path;
|
||||||
let alloc = Allocation::from_byte_aligned_bytes(path.into_bytes());
|
let alloc = Allocation::from_bytes_byte_aligned_immutable(path.into_bytes());
|
||||||
tcx.intern_const_alloc(alloc)
|
tcx.intern_const_alloc(alloc)
|
||||||
}
|
}
|
||||||
|
|
|
@ -219,9 +219,11 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
|
||||||
pub fn allocate_bytes(
|
pub fn allocate_bytes(
|
||||||
&mut self,
|
&mut self,
|
||||||
bytes: &[u8],
|
bytes: &[u8],
|
||||||
|
align: Align,
|
||||||
kind: MemoryKind<M::MemoryKind>,
|
kind: MemoryKind<M::MemoryKind>,
|
||||||
|
mutability: Mutability,
|
||||||
) -> Pointer<M::PointerTag> {
|
) -> Pointer<M::PointerTag> {
|
||||||
let alloc = Allocation::from_byte_aligned_bytes(bytes);
|
let alloc = Allocation::from_bytes(bytes, align, mutability);
|
||||||
self.allocate_with(alloc, kind)
|
self.allocate_with(alloc, kind)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@ use std::convert::TryFrom;
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
use std::hash::Hash;
|
use std::hash::Hash;
|
||||||
|
|
||||||
|
use rustc_ast::Mutability;
|
||||||
use rustc_macros::HashStable;
|
use rustc_macros::HashStable;
|
||||||
use rustc_middle::mir;
|
use rustc_middle::mir;
|
||||||
use rustc_middle::ty::layout::{PrimitiveExt, TyAndLayout};
|
use rustc_middle::ty::layout::{PrimitiveExt, TyAndLayout};
|
||||||
|
@ -1024,18 +1025,23 @@ where
|
||||||
MPlaceTy::from_aligned_ptr(ptr, layout)
|
MPlaceTy::from_aligned_ptr(ptr, layout)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a wide MPlace.
|
/// Returns a wide MPlace of type `&'static [mut] str` to a new 1-aligned allocation.
|
||||||
pub fn allocate_str(
|
pub fn allocate_str(
|
||||||
&mut self,
|
&mut self,
|
||||||
str: &str,
|
str: &str,
|
||||||
kind: MemoryKind<M::MemoryKind>,
|
kind: MemoryKind<M::MemoryKind>,
|
||||||
|
mutbl: Mutability,
|
||||||
) -> MPlaceTy<'tcx, M::PointerTag> {
|
) -> MPlaceTy<'tcx, M::PointerTag> {
|
||||||
let ptr = self.memory.allocate_bytes(str.as_bytes(), kind);
|
let ptr = self.memory.allocate_bytes(str.as_bytes(), Align::ONE, kind, mutbl);
|
||||||
let meta = Scalar::from_machine_usize(u64::try_from(str.len()).unwrap(), self);
|
let meta = Scalar::from_machine_usize(u64::try_from(str.len()).unwrap(), self);
|
||||||
let mplace =
|
let mplace =
|
||||||
MemPlace { ptr: ptr.into(), align: Align::ONE, meta: MemPlaceMeta::Meta(meta) };
|
MemPlace { ptr: ptr.into(), align: Align::ONE, meta: MemPlaceMeta::Meta(meta) };
|
||||||
|
|
||||||
let layout = self.layout_of(self.tcx.mk_static_str()).unwrap();
|
let ty = self.tcx.mk_ref(
|
||||||
|
self.tcx.lifetimes.re_static,
|
||||||
|
ty::TypeAndMut { ty: self.tcx.types.str_, mutbl },
|
||||||
|
);
|
||||||
|
let layout = self.layout_of(ty).unwrap();
|
||||||
MPlaceTy { mplace, layout }
|
MPlaceTy { mplace, layout }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,14 +25,14 @@ crate fn lit_to_const<'tcx>(
|
||||||
let lit = match (lit, &ty.kind()) {
|
let lit = match (lit, &ty.kind()) {
|
||||||
(ast::LitKind::Str(s, _), ty::Ref(_, inner_ty, _)) if inner_ty.is_str() => {
|
(ast::LitKind::Str(s, _), ty::Ref(_, inner_ty, _)) if inner_ty.is_str() => {
|
||||||
let s = s.as_str();
|
let s = s.as_str();
|
||||||
let allocation = Allocation::from_byte_aligned_bytes(s.as_bytes());
|
let allocation = Allocation::from_bytes_byte_aligned_immutable(s.as_bytes());
|
||||||
let allocation = tcx.intern_const_alloc(allocation);
|
let allocation = tcx.intern_const_alloc(allocation);
|
||||||
ConstValue::Slice { data: allocation, start: 0, end: s.len() }
|
ConstValue::Slice { data: allocation, start: 0, end: s.len() }
|
||||||
}
|
}
|
||||||
(ast::LitKind::ByteStr(data), ty::Ref(_, inner_ty, _))
|
(ast::LitKind::ByteStr(data), ty::Ref(_, inner_ty, _))
|
||||||
if matches!(inner_ty.kind(), ty::Slice(_)) =>
|
if matches!(inner_ty.kind(), ty::Slice(_)) =>
|
||||||
{
|
{
|
||||||
let allocation = Allocation::from_byte_aligned_bytes(data as &[u8]);
|
let allocation = Allocation::from_bytes_byte_aligned_immutable(data as &[u8]);
|
||||||
let allocation = tcx.intern_const_alloc(allocation);
|
let allocation = tcx.intern_const_alloc(allocation);
|
||||||
ConstValue::Slice { data: allocation, start: 0, end: data.len() }
|
ConstValue::Slice { data: allocation, start: 0, end: data.len() }
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue