about summary refs log tree commit diff
path: root/compiler/rustc_public/src/mir/alloc.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_public/src/mir/alloc.rs')
-rw-r--r--compiler/rustc_public/src/mir/alloc.rs90
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))
+        }
+    }
+}