diff options
| author | 许杰友 Jieyou Xu (Joe) <39484203+jieyouxu@users.noreply.github.com> | 2025-07-07 19:45:40 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-07-07 19:45:40 +0800 |
| commit | 02aa4ff12f09f8902b720ab7fc68d5ecfb84dda7 (patch) | |
| tree | ba9bebba4355a5b717467258c4481303e431b5e9 /compiler/rustc_smir/src/alloc.rs | |
| parent | 4ba4b5f24fbe54a158b32d94b33e5920777458d5 (diff) | |
| parent | 627cefa9930e65bc2ae4d93b8fb95b6f008f4702 (diff) | |
Rollup merge of #143524 - makai410:smir-move-back, r=oli-obk
Move `stable_mir` back to its own crate We've finished the refactoring, so it's time to move `stable_mir` back to its own crate. This PR leaves an empty `rustc_internal` module with a `#[deprecated]` attribute in `rustc_smir` to let users know we just moved it to `stable_mir`.
Diffstat (limited to 'compiler/rustc_smir/src/alloc.rs')
| -rw-r--r-- | compiler/rustc_smir/src/alloc.rs | 104 |
1 files changed, 104 insertions, 0 deletions
diff --git a/compiler/rustc_smir/src/alloc.rs b/compiler/rustc_smir/src/alloc.rs new file mode 100644 index 00000000000..cad643f3709 --- /dev/null +++ b/compiler/rustc_smir/src/alloc.rs @@ -0,0 +1,104 @@ +//! Internal memory allocator implementation for StableMIR. +//! +//! This module handles all direct interactions with rustc queries and performs +//! the actual memory allocations. The stable interface in `stable_mir::alloc` +//! delegates all query-related operations to this implementation. + +use rustc_abi::{Size, TyAndLayout}; +use rustc_middle::mir::interpret::{ + AllocId, AllocInit, AllocRange, Allocation, ConstAllocation, Pointer, Scalar, alloc_range, +}; +use rustc_middle::ty::{Ty, layout}; + +use super::{SmirCtxt, Tables}; +use crate::bridge::Allocation as _; +use crate::{Bridge, SmirError}; + +pub fn create_ty_and_layout<'tcx, B: Bridge>( + cx: &SmirCtxt<'tcx, B>, + ty: Ty<'tcx>, +) -> Result<TyAndLayout<'tcx, Ty<'tcx>>, &'tcx layout::LayoutError<'tcx>> { + use crate::context::SmirTypingEnv; + cx.tcx.layout_of(cx.fully_monomorphized().as_query_input(ty)) +} + +pub fn try_new_scalar<'tcx, B: Bridge>( + layout: TyAndLayout<'tcx, Ty<'tcx>>, + scalar: Scalar, + cx: &SmirCtxt<'tcx, B>, +) -> Result<Allocation, B::Error> { + let size = scalar.size(); + let mut allocation = Allocation::new(size, layout.align.abi, AllocInit::Uninit, ()); + allocation + .write_scalar(&cx.tcx, alloc_range(Size::ZERO, size), scalar) + .map_err(|e| B::Error::from_internal(e))?; + + Ok(allocation) +} + +pub fn try_new_slice<'tcx, B: Bridge>( + layout: TyAndLayout<'tcx, Ty<'tcx>>, + data: ConstAllocation<'tcx>, + meta: u64, + cx: &SmirCtxt<'tcx, B>, +) -> Result<Allocation, B::Error> { + let alloc_id = cx.tcx.reserve_and_set_memory_alloc(data); + let ptr = Pointer::new(alloc_id.into(), Size::ZERO); + let scalar_ptr = Scalar::from_pointer(ptr, &cx.tcx); + let scalar_meta: Scalar = Scalar::from_target_usize(meta, &cx.tcx); + let mut allocation = Allocation::new(layout.size, layout.align.abi, AllocInit::Uninit, ()); + allocation + .write_scalar(&cx.tcx, alloc_range(Size::ZERO, cx.tcx.data_layout.pointer_size), scalar_ptr) + .map_err(|e| B::Error::from_internal(e))?; + allocation + .write_scalar( + &cx.tcx, + alloc_range(cx.tcx.data_layout.pointer_size, scalar_meta.size()), + scalar_meta, + ) + .map_err(|e| B::Error::from_internal(e))?; + + Ok(allocation) +} + +pub fn try_new_indirect<'tcx, B: Bridge>( + alloc_id: AllocId, + cx: &SmirCtxt<'tcx, B>, +) -> ConstAllocation<'tcx> { + let alloc = cx.tcx.global_alloc(alloc_id).unwrap_memory(); + + alloc +} + +/// Creates an `Allocation` only from information within the `AllocRange`. +pub fn allocation_filter<'tcx, B: Bridge>( + alloc: &rustc_middle::mir::interpret::Allocation, + alloc_range: AllocRange, + tables: &mut Tables<'tcx, B>, + cx: &SmirCtxt<'tcx, B>, +) -> B::Allocation { + let mut bytes: Vec<Option<u8>> = alloc + .inspect_with_uninit_and_ptr_outside_interpreter( + alloc_range.start.bytes_usize()..alloc_range.end().bytes_usize(), + ) + .iter() + .copied() + .map(Some) + .collect(); + for (i, b) in bytes.iter_mut().enumerate() { + if !alloc.init_mask().get(Size::from_bytes(i + alloc_range.start.bytes_usize())) { + *b = None; + } + } + let mut ptrs = Vec::new(); + for (offset, prov) in alloc + .provenance() + .ptrs() + .iter() + .filter(|a| a.0 >= alloc_range.start && a.0 <= alloc_range.end()) + { + ptrs.push((offset.bytes_usize() - alloc_range.start.bytes_usize(), prov.alloc_id())); + } + + B::Allocation::new(bytes, ptrs, alloc.align.bytes(), alloc.mutability, tables, cx) +} |
