rustc_public/mir/
alloc.rs

1//! This module provides methods to retrieve allocation information, such as static variables.
2
3use std::io::Read;
4
5use serde::Serialize;
6
7use crate::mir::mono::{Instance, StaticDef};
8use crate::target::{Endian, MachineInfo};
9use crate::ty::{Allocation, Binder, ExistentialTraitRef, Ty};
10use crate::{Error, IndexedVal, with};
11
12/// An allocation in the rustc_public's IR global memory can be either a function pointer,
13/// a static, or a "real" allocation with some data in it.
14#[derive(Debug, Clone, Eq, PartialEq, Serialize)]
15pub enum GlobalAlloc {
16    /// The alloc ID is used as a function pointer.
17    Function(Instance),
18    /// This alloc ID points to a symbolic (not-reified) vtable.
19    /// The `None` trait ref is used to represent auto traits.
20    VTable(Ty, Option<Binder<ExistentialTraitRef>>),
21    /// The alloc ID points to a "lazy" static variable that did not get computed (yet).
22    /// This is also used to break the cycle in recursive statics.
23    Static(StaticDef),
24    /// The alloc ID points to memory.
25    Memory(Allocation),
26    /// The first pointer-sized segment of a type id. On 64 bit systems, the 128 bit type id
27    /// is split into two segments, on 32 bit systems there are 4 segments, and so on.
28    TypeId { ty: Ty },
29}
30
31impl From<AllocId> for GlobalAlloc {
32    fn from(value: AllocId) -> Self {
33        with(|cx| cx.global_alloc(value))
34    }
35}
36
37impl GlobalAlloc {
38    /// Retrieve the allocation id for a global allocation if it exists.
39    ///
40    /// For `[GlobalAlloc::VTable]`, this will return the allocation for the VTable of the given
41    /// type for the optional trait if the type implements the trait.
42    ///
43    /// This method will always return `None` for allocations other than `[GlobalAlloc::VTable]`.
44    pub fn vtable_allocation(&self) -> Option<AllocId> {
45        with(|cx| cx.vtable_allocation(self))
46    }
47}
48
49/// A unique identification number for each provenance
50#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Serialize)]
51pub struct AllocId(usize);
52
53impl IndexedVal for AllocId {
54    fn to_val(index: usize) -> Self {
55        AllocId(index)
56    }
57    fn to_index(&self) -> usize {
58        self.0
59    }
60}
61
62/// Utility function used to read an allocation data into a unassigned integer.
63pub(crate) fn read_target_uint(mut bytes: &[u8]) -> Result<u128, Error> {
64    let mut buf = [0u8; size_of::<u128>()];
65    match MachineInfo::target_endianness() {
66        Endian::Little => {
67            bytes.read_exact(&mut buf[..bytes.len()])?;
68            Ok(u128::from_le_bytes(buf))
69        }
70        Endian::Big => {
71            bytes.read_exact(&mut buf[16 - bytes.len()..])?;
72            Ok(u128::from_be_bytes(buf))
73        }
74    }
75}
76
77/// Utility function used to read an allocation data into an assigned integer.
78pub(crate) fn read_target_int(mut bytes: &[u8]) -> Result<i128, Error> {
79    let mut buf = [0u8; size_of::<i128>()];
80    match MachineInfo::target_endianness() {
81        Endian::Little => {
82            bytes.read_exact(&mut buf[..bytes.len()])?;
83            Ok(i128::from_le_bytes(buf))
84        }
85        Endian::Big => {
86            bytes.read_exact(&mut buf[16 - bytes.len()..])?;
87            Ok(i128::from_be_bytes(buf))
88        }
89    }
90}