6
6
use crate :: entity:: PrimaryMap ;
7
7
use crate :: ir:: StackSlot ;
8
8
use crate :: ir:: entities:: { DynamicStackSlot , DynamicType } ;
9
- use alloc:: vec:: Vec ;
10
9
use core:: fmt;
11
10
use core:: str:: FromStr ;
12
11
@@ -71,25 +70,62 @@ pub struct StackSlotData {
71
70
/// stack slot size or machine word size, as well.
72
71
pub align_shift : u8 ,
73
72
74
- /// Opaque stackslot metadata, passed through to compilation
75
- /// result metadata describing stackslot location.
73
+ /// Opaque stackslot metadata handle , passed through to
74
+ /// compilation result metadata describing stackslot location.
76
75
///
77
76
/// In the face of compiler transforms like inlining that may move
78
77
/// stackslots between functions, when an embedder wants to
79
78
/// externally observe stackslots, it needs a first-class way for
80
79
/// the identity of stackslots to be carried along with the IR
81
- /// entities. This opaque data allows the embedder to do that.
82
- pub descriptor : Vec < u8 > ,
80
+ /// entities. This opaque `StackSlotKey` allows the embedder to do
81
+ /// so.
82
+ pub key : Option < StackSlotKey > ,
83
+ }
84
+
85
+ /// An opaque key uniquely identifying a stack slot.
86
+ #[ derive( Clone , Copy , Debug , PartialEq , Eq , Hash ) ]
87
+ #[ cfg_attr( feature = "enable-serde" , derive( Serialize , Deserialize ) ) ]
88
+ pub struct StackSlotKey ( u64 ) ;
89
+ impl StackSlotKey {
90
+ /// Construct a [`StackSlotKey`] from raw bits.
91
+ ///
92
+ /// An embedder can use any 64-bit value to describe a stack slot;
93
+ /// there are no restrictions, and the value does not mean
94
+ /// anything to Cranelift itself.
95
+ pub fn new ( value : u64 ) -> StackSlotKey {
96
+ StackSlotKey ( value)
97
+ }
98
+
99
+ /// Get the raw bits from the [`StackSlotKey`].
100
+ pub fn bits ( & self ) -> u64 {
101
+ self . 0
102
+ }
83
103
}
84
104
85
105
impl StackSlotData {
86
106
/// Create a stack slot with the specified byte size and alignment.
87
- pub fn new ( kind : StackSlotKind , size : StackSize , align_shift : u8 , descriptor : Vec < u8 > ) -> Self {
107
+ pub fn new ( kind : StackSlotKind , size : StackSize , align_shift : u8 ) -> Self {
108
+ Self {
109
+ kind,
110
+ size,
111
+ align_shift,
112
+ key : None ,
113
+ }
114
+ }
115
+
116
+ /// Create a stack slot with the specified byte size and alignment
117
+ /// and the given user-defined key.
118
+ pub fn new_with_key (
119
+ kind : StackSlotKind ,
120
+ size : StackSize ,
121
+ align_shift : u8 ,
122
+ key : StackSlotKey ,
123
+ ) -> Self {
88
124
Self {
89
125
kind,
90
126
size,
91
127
align_shift,
92
- descriptor ,
128
+ key : Some ( key ) ,
93
129
}
94
130
}
95
131
}
@@ -101,12 +137,12 @@ impl fmt::Display for StackSlotData {
101
137
} else {
102
138
"" . into ( )
103
139
} ;
104
- let descriptor = if !self . descriptor . is_empty ( ) {
105
- format ! ( ", descriptor = {:?}" , self . descriptor)
106
- } else {
107
- "" . into ( )
140
+ let key = match self . key {
141
+ Some ( value) => format ! ( ", key = {}" , value. bits( ) ) ,
142
+ None => "" . into ( ) ,
108
143
} ;
109
- write ! ( f, "{} {}{align_shift}{descriptor}" , self . kind, self . size)
144
+
145
+ write ! ( f, "{} {}{align_shift}{key}" , self . kind, self . size)
110
146
}
111
147
}
112
148
@@ -159,18 +195,10 @@ mod tests {
159
195
fn stack_slot ( ) {
160
196
let mut func = Function :: new ( ) ;
161
197
162
- let ss0 = func. create_sized_stack_slot ( StackSlotData :: new (
163
- StackSlotKind :: ExplicitSlot ,
164
- 4 ,
165
- 0 ,
166
- vec ! [ ] ,
167
- ) ) ;
168
- let ss1 = func. create_sized_stack_slot ( StackSlotData :: new (
169
- StackSlotKind :: ExplicitSlot ,
170
- 8 ,
171
- 0 ,
172
- vec ! [ ] ,
173
- ) ) ;
198
+ let ss0 =
199
+ func. create_sized_stack_slot ( StackSlotData :: new ( StackSlotKind :: ExplicitSlot , 4 , 0 ) ) ;
200
+ let ss1 =
201
+ func. create_sized_stack_slot ( StackSlotData :: new ( StackSlotKind :: ExplicitSlot , 8 , 0 ) ) ;
174
202
assert_eq ! ( ss0. to_string( ) , "ss0" ) ;
175
203
assert_eq ! ( ss1. to_string( ) , "ss1" ) ;
176
204
0 commit comments