Skip to content

Commit 5a77f1d

Browse files
committed
Add support to global allocation to stable-mir
1 parent 4d7f952 commit 5a77f1d

File tree

9 files changed

+158
-28
lines changed

9 files changed

+158
-28
lines changed

compiler/rustc_smir/src/rustc_internal/internal.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,13 @@
77
use crate::rustc_smir::Tables;
88
use rustc_middle::ty::{self as rustc_ty, Ty as InternalTy};
99
use rustc_span::Symbol;
10+
use stable_mir::mir::alloc::AllocId;
1011
use stable_mir::mir::mono::{Instance, MonoItem, StaticDef};
1112
use stable_mir::ty::{
1213
Binder, BoundRegionKind, BoundTyKind, BoundVariableKind, ClosureKind, Const, GenericArgKind,
1314
GenericArgs, Region, TraitRef, Ty,
1415
};
15-
use stable_mir::{AllocId, CrateItem, DefId};
16+
use stable_mir::{CrateItem, DefId};
1617

1718
use super::RustcInternal;
1819

compiler/rustc_smir/src/rustc_internal/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ impl<'tcx> Tables<'tcx> {
117117
self.def_ids.create_or_fetch(did)
118118
}
119119

120-
fn create_alloc_id(&mut self, aid: AllocId) -> stable_mir::AllocId {
120+
fn create_alloc_id(&mut self, aid: AllocId) -> stable_mir::mir::alloc::AllocId {
121121
self.alloc_ids.create_or_fetch(aid)
122122
}
123123

compiler/rustc_smir/src/rustc_smir/mod.rs

Lines changed: 72 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,11 @@ use rustc_middle::mir::mono::MonoItem;
1717
use rustc_middle::ty::{self, Instance, ParamEnv, Ty, TyCtxt, Variance};
1818
use rustc_span::def_id::{CrateNum, DefId, LOCAL_CRATE};
1919
use rustc_target::abi::FieldIdx;
20-
use stable_mir::mir::mono::InstanceDef;
20+
use stable_mir::mir::alloc::GlobalAlloc;
21+
use stable_mir::mir::mono::{InstanceDef, StaticDef};
2122
use stable_mir::mir::{Body, CopyNonOverlapping, Statement, UserTypeProjection, VariantIdx};
22-
use stable_mir::ty::{
23-
AdtDef, AdtKind, ClosureDef, ClosureKind, Const, ConstId, ConstantKind, EarlyParamRegion,
24-
FloatTy, FnDef, GenericArgs, GenericParamDef, IntTy, LineInfo, Movability, RigidTy, Span,
25-
TyKind, UintTy,
26-
};
27-
use stable_mir::{self, opaque, Context, CrateItem, Filename, ItemKind};
23+
use stable_mir::ty::{AdtDef, AdtKind, Allocation, ClosureDef, ClosureKind, Const, ConstId, ConstantKind, FloatTy, FnDef, GenericArgs, GenericParamDef, IntTy, LineInfo, Movability, RigidTy, Span, TyKind, UintTy, EarlyParamRegion};
24+
use stable_mir::{self, opaque, Context, CrateItem, Error, Filename, ItemKind};
2825
use std::cell::RefCell;
2926
use tracing::debug;
3027

@@ -91,6 +88,11 @@ impl<'tcx> Context for TablesWrapper<'tcx> {
9188
new_item_kind(tables.tcx.def_kind(tables[item.0]))
9289
}
9390

91+
fn is_foreign_item(&self, item: CrateItem) -> bool {
92+
let tables = self.0.borrow();
93+
tables.tcx.is_foreign_item(tables[item.0])
94+
}
95+
9496
fn adt_kind(&self, def: AdtDef) -> AdtKind {
9597
let mut tables = self.0.borrow_mut();
9698
let ty = tables.tcx.type_of(def.0.internal(&mut *tables)).instantiate_identity().kind();
@@ -298,14 +300,26 @@ impl<'tcx> Context for TablesWrapper<'tcx> {
298300
let closure_kind = kind.internal(&mut *tables);
299301
Instance::resolve_closure(tables.tcx, def_id, args_ref, closure_kind).stable(&mut *tables)
300302
}
303+
304+
fn eval_static_initializer(&self, def: StaticDef) -> Result<Allocation, Error> {
305+
let mut tables = self.0.borrow_mut();
306+
let def_id = def.0.internal(&mut *tables);
307+
tables.tcx.eval_static_initializer(def_id).stable(&mut *tables)
308+
}
309+
310+
fn global_alloc(&self, alloc: stable_mir::mir::alloc::AllocId) -> GlobalAlloc {
311+
let mut tables = self.0.borrow_mut();
312+
let alloc_id = alloc.internal(&mut *tables);
313+
tables.tcx.global_alloc(alloc_id).stable(&mut *tables)
314+
}
301315
}
302316

303317
pub(crate) struct TablesWrapper<'tcx>(pub(crate) RefCell<Tables<'tcx>>);
304318

305319
pub struct Tables<'tcx> {
306320
pub(crate) tcx: TyCtxt<'tcx>,
307321
pub(crate) def_ids: IndexMap<DefId, stable_mir::DefId>,
308-
pub(crate) alloc_ids: IndexMap<AllocId, stable_mir::AllocId>,
322+
pub(crate) alloc_ids: IndexMap<AllocId, stable_mir::mir::alloc::AllocId>,
309323
pub(crate) spans: IndexMap<rustc_span::Span, Span>,
310324
pub(crate) types: IndexMap<Ty<'tcx>, stable_mir::ty::Ty>,
311325
pub(crate) instances: IndexMap<ty::Instance<'tcx>, InstanceDef>,
@@ -1502,6 +1516,14 @@ impl<'tcx> Stable<'tcx> for ty::BoundTy {
15021516
}
15031517
}
15041518

1519+
impl<'tcx> Stable<'tcx> for mir::interpret::ConstAllocation<'tcx> {
1520+
type T = Allocation;
1521+
1522+
fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
1523+
self.inner().stable(tables)
1524+
}
1525+
}
1526+
15051527
impl<'tcx> Stable<'tcx> for mir::interpret::Allocation {
15061528
type T = stable_mir::ty::Allocation;
15071529

@@ -1514,6 +1536,25 @@ impl<'tcx> Stable<'tcx> for mir::interpret::Allocation {
15141536
}
15151537
}
15161538

1539+
impl<'tcx> Stable<'tcx> for mir::interpret::GlobalAlloc<'tcx> {
1540+
type T = GlobalAlloc;
1541+
1542+
fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
1543+
match self {
1544+
mir::interpret::GlobalAlloc::Function(instance) => {
1545+
GlobalAlloc::Function(instance.stable(tables))
1546+
}
1547+
mir::interpret::GlobalAlloc::VTable(ty, trait_ref) => {
1548+
GlobalAlloc::VTable(ty.stable(tables), trait_ref.stable(tables))
1549+
}
1550+
mir::interpret::GlobalAlloc::Static(def) => {
1551+
GlobalAlloc::Static(tables.static_def(*def))
1552+
}
1553+
mir::interpret::GlobalAlloc::Memory(alloc) => GlobalAlloc::Memory(alloc.stable(tables)),
1554+
}
1555+
}
1556+
}
1557+
15171558
impl<'tcx> Stable<'tcx> for ty::trait_def::TraitSpecializationKind {
15181559
type T = stable_mir::ty::TraitSpecializationKind;
15191560
fn stable(&self, _: &mut Tables<'tcx>) -> Self::T {
@@ -1901,6 +1942,14 @@ impl<'tcx> Stable<'tcx> for MonoItem<'tcx> {
19011942
}
19021943
}
19031944

1945+
impl<'tcx> Stable<'tcx> for mir::interpret::ErrorHandled {
1946+
type T = Error;
1947+
1948+
fn stable(&self, _tables: &mut Tables<'tcx>) -> Self::T {
1949+
Error::new(format!("{self:?}"))
1950+
}
1951+
}
1952+
19041953
impl<'tcx, T> Stable<'tcx> for &T
19051954
where
19061955
T: Stable<'tcx>,
@@ -1922,3 +1971,18 @@ where
19221971
self.as_ref().map(|value| value.stable(tables))
19231972
}
19241973
}
1974+
1975+
impl<'tcx, T, E> Stable<'tcx> for Result<T, E>
1976+
where
1977+
T: Stable<'tcx>,
1978+
E: Stable<'tcx>,
1979+
{
1980+
type T = Result<T::T, E::T>;
1981+
1982+
fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
1983+
match self {
1984+
Ok(val) => Ok(val.stable(tables)),
1985+
Err(error) => Err(error.stable(tables)),
1986+
}
1987+
}
1988+
}

compiler/stable_mir/src/error.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ pub enum CompilerError<T> {
2727
pub struct Error(String);
2828

2929
impl Error {
30-
pub(crate) fn new(msg: String) -> Self {
30+
pub fn new(msg: String) -> Self {
3131
Self(msg)
3232
}
3333
}

compiler/stable_mir/src/lib.rs

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
//! The goal is to eventually be published on
1818
//! [crates.io](https://crates.io).
1919
20-
use crate::mir::mono::InstanceDef;
20+
use crate::mir::mono::{InstanceDef, StaticDef};
2121
use crate::mir::Body;
2222
use std::cell::Cell;
2323
use std::fmt;
@@ -36,7 +36,8 @@ pub mod mir;
3636
pub mod ty;
3737
pub mod visitor;
3838

39-
use crate::ty::{AdtDef, AdtKind, ClosureDef, ClosureKind};
39+
use crate::mir::alloc::{AllocId, GlobalAlloc};
40+
use crate::ty::{AdtDef, AdtKind, Allocation, ClosureDef, ClosureKind};
4041
pub use error::*;
4142
use mir::mono::Instance;
4243
use ty::{FnDef, GenericArgs};
@@ -70,19 +71,6 @@ impl IndexedVal for DefId {
7071
}
7172
}
7273

73-
/// A unique identification number for each provenance
74-
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
75-
pub struct AllocId(usize);
76-
77-
impl IndexedVal for AllocId {
78-
fn to_val(index: usize) -> Self {
79-
AllocId(index)
80-
}
81-
fn to_index(&self) -> usize {
82-
self.0
83-
}
84-
}
85-
8674
/// A list of crate items.
8775
pub type CrateItems = Vec<CrateItem>;
8876

@@ -137,6 +125,10 @@ impl CrateItem {
137125
pub fn ty(&self) -> Ty {
138126
with(|cx| cx.def_ty(self.0))
139127
}
128+
129+
pub fn is_foreign_item(&self) -> bool {
130+
with(|cx| cx.is_foreign_item(*self))
131+
}
140132
}
141133

142134
/// Return the function where execution starts if the current
@@ -182,6 +174,8 @@ pub fn trait_impl(trait_impl: &ImplDef) -> ImplTrait {
182174
with(|cx| cx.trait_impl(trait_impl))
183175
}
184176

177+
/// This trait defines the interface between stable_mir and the Rust compiler.
178+
/// Do not use this directly.
185179
pub trait Context {
186180
fn entry_fn(&self) -> Option<CrateItem>;
187181
/// Retrieve all items of the local crate that have a MIR associated with them.
@@ -217,6 +211,9 @@ pub trait Context {
217211
/// Returns the `kind` of given `DefId`
218212
fn item_kind(&self, item: CrateItem) -> ItemKind;
219213

214+
/// Returns whether this is a foreign item.
215+
fn is_foreign_item(&self, item: CrateItem) -> bool;
216+
220217
/// Returns the kind of a given algebraic data type
221218
fn adt_kind(&self, def: AdtDef) -> AdtKind;
222219

@@ -265,6 +262,12 @@ pub trait Context {
265262
args: &GenericArgs,
266263
kind: ClosureKind,
267264
) -> Option<Instance>;
265+
266+
/// Evaluate a static's initializer.
267+
fn eval_static_initializer(&self, def: StaticDef) -> Result<Allocation, Error>;
268+
269+
/// Retrieve global allocation for the given allocation ID.
270+
fn global_alloc(&self, id: AllocId) -> GlobalAlloc;
268271
}
269272

270273
// A thread local variable that stores a pointer to the tables mapping between TyCtxt

compiler/stable_mir/src/mir.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
pub mod alloc;
12
mod body;
23
pub mod mono;
34
pub mod visit;

compiler/stable_mir/src/mir/alloc.rs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
use crate::mir::mono::{Instance, StaticDef};
2+
use crate::ty::{Allocation, Binder, ExistentialTraitRef, IndexedVal, Ty};
3+
use crate::with;
4+
5+
/// An allocation in the SMIR global memory can be either a function pointer,
6+
/// a static, or a "real" allocation with some data in it.
7+
#[derive(Debug, Clone, Eq, PartialEq)]
8+
pub enum GlobalAlloc {
9+
/// The alloc ID is used as a function pointer.
10+
Function(Instance),
11+
/// This alloc ID points to a symbolic (not-reified) vtable.
12+
VTable(Ty, Option<Binder<ExistentialTraitRef>>),
13+
/// The alloc ID points to a "lazy" static variable that did not get computed (yet).
14+
/// This is also used to break the cycle in recursive statics.
15+
Static(StaticDef),
16+
/// The alloc ID points to memory.
17+
Memory(Allocation),
18+
}
19+
20+
impl From<AllocId> for GlobalAlloc {
21+
fn from(value: AllocId) -> Self {
22+
with(|cx| cx.global_alloc(value))
23+
}
24+
}
25+
26+
/// A unique identification number for each provenance
27+
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
28+
pub struct AllocId(usize);
29+
30+
impl IndexedVal for AllocId {
31+
fn to_val(index: usize) -> Self {
32+
AllocId(index)
33+
}
34+
fn to_index(&self) -> usize {
35+
self.0
36+
}
37+
}

compiler/stable_mir/src/mir/mono.rs

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::mir::Body;
2-
use crate::ty::{ClosureDef, ClosureKind, FnDef, GenericArgs, IndexedVal, Ty};
2+
use crate::ty::{Allocation, ClosureDef, ClosureKind, FnDef, GenericArgs, IndexedVal, Ty};
33
use crate::{with, CrateItem, DefId, Error, ItemKind, Opaque};
44
use std::fmt::Debug;
55

@@ -37,6 +37,11 @@ impl Instance {
3737
with(|context| context.instance_body(self.def))
3838
}
3939

40+
pub fn is_foreign_item(&self) -> bool {
41+
let item = CrateItem::try_from(*self);
42+
item.as_ref().map_or(false, CrateItem::is_foreign_item)
43+
}
44+
4045
/// Get the instance type with generic substitutions applied and lifetimes erased.
4146
pub fn ty(&self) -> Ty {
4247
with(|context| context.instance_ty(self.def))
@@ -119,6 +124,18 @@ impl From<Instance> for MonoItem {
119124
}
120125
}
121126

127+
impl From<StaticDef> for MonoItem {
128+
fn from(value: StaticDef) -> Self {
129+
MonoItem::Static(value)
130+
}
131+
}
132+
133+
impl From<StaticDef> for CrateItem {
134+
fn from(value: StaticDef) -> Self {
135+
CrateItem(value.0)
136+
}
137+
}
138+
122139
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
123140
pub struct InstanceDef(usize);
124141

@@ -138,9 +155,15 @@ impl TryFrom<CrateItem> for StaticDef {
138155
}
139156

140157
impl StaticDef {
158+
/// Return the type of this static definition.
141159
pub fn ty(&self) -> Ty {
142160
with(|cx| cx.def_ty(self.0))
143161
}
162+
163+
/// Evaluate a static's initializer, returning the allocation of the initializer's memory.
164+
pub fn eval_initializer(&self) -> Result<Allocation, Error> {
165+
with(|cx| cx.eval_static_initializer(*self))
166+
}
144167
}
145168

146169
impl IndexedVal for InstanceDef {

compiler/stable_mir/src/ty.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
use super::{
22
mir::Safety,
33
mir::{Body, Mutability},
4-
with, AllocId, DefId, Symbol,
4+
with, DefId, Symbol,
55
};
6+
use crate::mir::alloc::AllocId;
67
use crate::{Filename, Opaque};
78
use std::fmt::{self, Debug, Display, Formatter};
89

0 commit comments

Comments
 (0)