diff options
Diffstat (limited to 'compiler/rustc_public/src/mir/alloc.rs')
| -rw-r--r-- | compiler/rustc_public/src/mir/alloc.rs | 90 |
1 files changed, 90 insertions, 0 deletions
diff --git a/compiler/rustc_public/src/mir/alloc.rs b/compiler/rustc_public/src/mir/alloc.rs new file mode 100644 index 00000000000..9a94551f3ec --- /dev/null +++ b/compiler/rustc_public/src/mir/alloc.rs @@ -0,0 +1,90 @@ +//! This module provides methods to retrieve allocation information, such as static variables. + +use std::io::Read; + +use serde::Serialize; + +use crate::mir::mono::{Instance, StaticDef}; +use crate::target::{Endian, MachineInfo}; +use crate::ty::{Allocation, Binder, ExistentialTraitRef, Ty}; +use crate::{Error, IndexedVal, with}; + +/// An allocation in the SMIR global memory can be either a function pointer, +/// a static, or a "real" allocation with some data in it. +#[derive(Debug, Clone, Eq, PartialEq, Serialize)] +pub enum GlobalAlloc { + /// The alloc ID is used as a function pointer. + Function(Instance), + /// This alloc ID points to a symbolic (not-reified) vtable. + /// The `None` trait ref is used to represent auto traits. + VTable(Ty, Option<Binder<ExistentialTraitRef>>), + /// The alloc ID points to a "lazy" static variable that did not get computed (yet). + /// This is also used to break the cycle in recursive statics. + Static(StaticDef), + /// The alloc ID points to memory. + Memory(Allocation), + /// The first pointer-sized segment of a type id. On 64 bit systems, the 128 bit type id + /// is split into two segments, on 32 bit systems there are 4 segments, and so on. + TypeId { ty: Ty }, +} + +impl From<AllocId> for GlobalAlloc { + fn from(value: AllocId) -> Self { + with(|cx| cx.global_alloc(value)) + } +} + +impl GlobalAlloc { + /// Retrieve the allocation id for a global allocation if it exists. + /// + /// For `[GlobalAlloc::VTable]`, this will return the allocation for the VTable of the given + /// type for the optional trait if the type implements the trait. + /// + /// This method will always return `None` for allocations other than `[GlobalAlloc::VTable]`. + pub fn vtable_allocation(&self) -> Option<AllocId> { + with(|cx| cx.vtable_allocation(self)) + } +} + +/// A unique identification number for each provenance +#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Serialize)] +pub struct AllocId(usize); + +impl IndexedVal for AllocId { + fn to_val(index: usize) -> Self { + AllocId(index) + } + fn to_index(&self) -> usize { + self.0 + } +} + +/// Utility function used to read an allocation data into a unassigned integer. +pub(crate) fn read_target_uint(mut bytes: &[u8]) -> Result<u128, Error> { + let mut buf = [0u8; size_of::<u128>()]; + match MachineInfo::target_endianness() { + Endian::Little => { + bytes.read_exact(&mut buf[..bytes.len()])?; + Ok(u128::from_le_bytes(buf)) + } + Endian::Big => { + bytes.read_exact(&mut buf[16 - bytes.len()..])?; + Ok(u128::from_be_bytes(buf)) + } + } +} + +/// Utility function used to read an allocation data into an assigned integer. +pub(crate) fn read_target_int(mut bytes: &[u8]) -> Result<i128, Error> { + let mut buf = [0u8; size_of::<i128>()]; + match MachineInfo::target_endianness() { + Endian::Little => { + bytes.read_exact(&mut buf[..bytes.len()])?; + Ok(i128::from_le_bytes(buf)) + } + Endian::Big => { + bytes.read_exact(&mut buf[16 - bytes.len()..])?; + Ok(i128::from_be_bytes(buf)) + } + } +} |
