Skip to content

Commit f230dd0

Browse files
committed
Add support to global allocation to stable-mir
1 parent 46ecc10 commit f230dd0

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
@@ -118,7 +118,7 @@ impl<'tcx> Tables<'tcx> {
118118
self.def_ids.create_or_fetch(did)
119119
}
120120

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

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();
@@ -302,14 +304,26 @@ impl<'tcx> Context for TablesWrapper<'tcx> {
302304
let closure_kind = kind.internal(&mut *tables);
303305
Instance::resolve_closure(tables.tcx, def_id, args_ref, closure_kind).stable(&mut *tables)
304306
}
307+
308+
fn eval_static_initializer(&self, def: StaticDef) -> Result<Allocation, Error> {
309+
let mut tables = self.0.borrow_mut();
310+
let def_id = def.0.internal(&mut *tables);
311+
tables.tcx.eval_static_initializer(def_id).stable(&mut *tables)
312+
}
313+
314+
fn global_alloc(&self, alloc: stable_mir::mir::alloc::AllocId) -> GlobalAlloc {
315+
let mut tables = self.0.borrow_mut();
316+
let alloc_id = alloc.internal(&mut *tables);
317+
tables.tcx.global_alloc(alloc_id).stable(&mut *tables)
318+
}
305319
}
306320

307321
pub(crate) struct TablesWrapper<'tcx>(pub(crate) RefCell<Tables<'tcx>>);
308322

309323
pub struct Tables<'tcx> {
310324
pub(crate) tcx: TyCtxt<'tcx>,
311325
pub(crate) def_ids: IndexMap<DefId, stable_mir::DefId>,
312-
pub(crate) alloc_ids: IndexMap<AllocId, stable_mir::AllocId>,
326+
pub(crate) alloc_ids: IndexMap<AllocId, stable_mir::mir::alloc::AllocId>,
313327
pub(crate) spans: IndexMap<rustc_span::Span, Span>,
314328
pub(crate) types: IndexMap<Ty<'tcx>, stable_mir::ty::Ty>,
315329
pub(crate) instances: IndexMap<ty::Instance<'tcx>, InstanceDef>,
@@ -1507,6 +1521,14 @@ impl<'tcx> Stable<'tcx> for ty::BoundTy {
15071521
}
15081522
}
15091523

1524+
impl<'tcx> Stable<'tcx> for mir::interpret::ConstAllocation<'tcx> {
1525+
type T = Allocation;
1526+
1527+
fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
1528+
self.inner().stable(tables)
1529+
}
1530+
}
1531+
15101532
impl<'tcx> Stable<'tcx> for mir::interpret::Allocation {
15111533
type T = stable_mir::ty::Allocation;
15121534

@@ -1519,6 +1541,25 @@ impl<'tcx> Stable<'tcx> for mir::interpret::Allocation {
15191541
}
15201542
}
15211543

1544+
impl<'tcx> Stable<'tcx> for mir::interpret::GlobalAlloc<'tcx> {
1545+
type T = GlobalAlloc;
1546+
1547+
fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
1548+
match self {
1549+
mir::interpret::GlobalAlloc::Function(instance) => {
1550+
GlobalAlloc::Function(instance.stable(tables))
1551+
}
1552+
mir::interpret::GlobalAlloc::VTable(ty, trait_ref) => {
1553+
GlobalAlloc::VTable(ty.stable(tables), trait_ref.stable(tables))
1554+
}
1555+
mir::interpret::GlobalAlloc::Static(def) => {
1556+
GlobalAlloc::Static(tables.static_def(*def))
1557+
}
1558+
mir::interpret::GlobalAlloc::Memory(alloc) => GlobalAlloc::Memory(alloc.stable(tables)),
1559+
}
1560+
}
1561+
}
1562+
15221563
impl<'tcx> Stable<'tcx> for ty::trait_def::TraitSpecializationKind {
15231564
type T = stable_mir::ty::TraitSpecializationKind;
15241565
fn stable(&self, _: &mut Tables<'tcx>) -> Self::T {
@@ -1906,6 +1947,14 @@ impl<'tcx> Stable<'tcx> for MonoItem<'tcx> {
19061947
}
19071948
}
19081949

1950+
impl<'tcx> Stable<'tcx> for mir::interpret::ErrorHandled {
1951+
type T = Error;
1952+
1953+
fn stable(&self, _tables: &mut Tables<'tcx>) -> Self::T {
1954+
Error::new(format!("{self:?}"))
1955+
}
1956+
}
1957+
19091958
impl<'tcx, T> Stable<'tcx> for &T
19101959
where
19111960
T: Stable<'tcx>,
@@ -1927,3 +1976,18 @@ where
19271976
self.as_ref().map(|value| value.stable(tables))
19281977
}
19291978
}
1979+
1980+
impl<'tcx, T, E> Stable<'tcx> for Result<T, E>
1981+
where
1982+
T: Stable<'tcx>,
1983+
E: Stable<'tcx>,
1984+
{
1985+
type T = Result<T::T, E::T>;
1986+
1987+
fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
1988+
match self {
1989+
Ok(val) => Ok(val.stable(tables)),
1990+
Err(error) => Err(error.stable(tables)),
1991+
}
1992+
}
1993+
}

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::fmt;
2323
use std::fmt::Debug;
@@ -36,9 +36,10 @@ pub mod mir;
3636
pub mod ty;
3737
pub mod visitor;
3838

39+
use crate::mir::alloc::{AllocId, GlobalAlloc};
3940
use crate::mir::pretty::function_name;
4041
use crate::mir::Mutability;
41-
use crate::ty::{AdtDef, AdtKind, ClosureDef, ClosureKind};
42+
use crate::ty::{AdtDef, AdtKind, Allocation, ClosureDef, ClosureKind};
4243
pub use error::*;
4344
use mir::mono::Instance;
4445
use ty::{Const, FnDef, GenericArgs};
@@ -72,19 +73,6 @@ impl IndexedVal for DefId {
7273
}
7374
}
7475

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

@@ -140,6 +128,10 @@ impl CrateItem {
140128
with(|cx| cx.def_ty(self.0))
141129
}
142130

131+
pub fn is_foreign_item(&self) -> bool {
132+
with(|cx| cx.is_foreign_item(*self))
133+
}
134+
143135
pub fn dump<W: io::Write>(&self, w: &mut W) -> io::Result<()> {
144136
writeln!(w, "{}", function_name(*self))?;
145137
self.body().dump(w)
@@ -189,6 +181,8 @@ pub fn trait_impl(trait_impl: &ImplDef) -> ImplTrait {
189181
with(|cx| cx.trait_impl(trait_impl))
190182
}
191183

184+
/// This trait defines the interface between stable_mir and the Rust compiler.
185+
/// Do not use this directly.
192186
pub trait Context {
193187
fn entry_fn(&self) -> Option<CrateItem>;
194188
/// Retrieve all items of the local crate that have a MIR associated with them.
@@ -224,6 +218,9 @@ pub trait Context {
224218
/// Returns the `kind` of given `DefId`
225219
fn item_kind(&self, item: CrateItem) -> ItemKind;
226220

221+
/// Returns whether this is a foreign item.
222+
fn is_foreign_item(&self, item: CrateItem) -> bool;
223+
227224
/// Returns the kind of a given algebraic data type
228225
fn adt_kind(&self, def: AdtDef) -> AdtKind;
229226

@@ -275,6 +272,12 @@ pub trait Context {
275272
args: &GenericArgs,
276273
kind: ClosureKind,
277274
) -> Option<Instance>;
275+
276+
/// Evaluate a static's initializer.
277+
fn eval_static_initializer(&self, def: StaticDef) -> Result<Allocation, Error>;
278+
279+
/// Retrieve global allocation for the given allocation ID.
280+
fn global_alloc(&self, id: AllocId) -> GlobalAlloc;
278281
}
279282

280283
// 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 pretty;

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)