Next Generation WASM Microkernel Operating System
1// Copyright 2025 Jonas Kruckenberg
2//
3// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
4// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
5// http://opensource.org/licenses/MIT>, at your option. This file may not be
6// copied, modified, or distributed except according to those terms.
7
8use crate::wasm::utils::enum_accessors;
9use cranelift_entity::entity_impl;
10
11#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
12pub struct TypeIndex(u32);
13entity_impl!(TypeIndex);
14
15#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
16pub struct FuncIndex(u32);
17entity_impl!(FuncIndex);
18
19#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
20pub struct DefinedFuncIndex(u32);
21entity_impl!(DefinedFuncIndex);
22
23#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
24pub struct TableIndex(u32);
25entity_impl!(TableIndex);
26
27#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
28pub struct DefinedTableIndex(u32);
29entity_impl!(DefinedTableIndex);
30
31#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
32pub struct MemoryIndex(u32);
33entity_impl!(MemoryIndex);
34
35#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
36pub struct DefinedMemoryIndex(u32);
37entity_impl!(DefinedMemoryIndex);
38
39#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
40pub struct OwnedMemoryIndex(u32);
41entity_impl!(OwnedMemoryIndex);
42
43#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
44pub struct GlobalIndex(u32);
45entity_impl!(GlobalIndex);
46
47#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
48pub struct DefinedGlobalIndex(u32);
49entity_impl!(DefinedGlobalIndex);
50
51#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
52pub struct DefinedTagIndex(u32);
53entity_impl!(DefinedTagIndex);
54
55#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
56pub struct ElemIndex(u32);
57entity_impl!(ElemIndex);
58
59#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
60pub struct DataIndex(u32);
61entity_impl!(DataIndex);
62
63#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
64pub struct FuncRefIndex(u32);
65entity_impl!(FuncRefIndex);
66
67#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
68pub struct LocalIndex(u32);
69entity_impl!(LocalIndex);
70
71#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
72pub struct FieldIndex(u32);
73entity_impl!(FieldIndex);
74
75#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
76pub struct TagIndex(u32);
77entity_impl!(TagIndex);
78
79/// A reference to a label in a function. Only used for associating label names.
80///
81/// NOTE: These indices are local to the function they used in, they are also
82/// **not** the same as the depth of their block. This means you cant just go
83/// and take the relative branch depth of a `br` instruction and the label stack
84/// height to get the label index.
85/// According to the proposal the labels are assigned indices in the order their
86/// blocks appear in the code.
87///
88/// Source:
89/// <https://github.com/WebAssembly/extended-name-section/blob/main/proposals/extended-name-section/Overview.md#label-names>
90///
91/// ALSO NOTE: No existing tooling appears to emit label names, so this just doesn't
92/// appear in the wild probably.
93#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
94pub struct LabelIndex(u32);
95entity_impl!(LabelIndex);
96
97#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
98pub enum EntityIndex {
99 Function(FuncIndex),
100 Table(TableIndex),
101 Memory(MemoryIndex),
102 Global(GlobalIndex),
103 Tag(TagIndex),
104}
105
106impl EntityIndex {
107 enum_accessors! {
108 e
109 (Function(FuncIndex) is_func func unwrap_func *e)
110 (Table(TableIndex) is_table table unwrap_table *e)
111 (Memory(MemoryIndex) is_memory memory unwrap_memory *e)
112 (Global(GlobalIndex) is_global global unwrap_global *e)
113 (Tag(TagIndex) is_tag tag unwrap_tag *e)
114 }
115}
116
117#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
118pub struct ModuleInternedTypeIndex(u32);
119entity_impl!(ModuleInternedTypeIndex);
120
121#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
122pub struct ModuleInternedRecGroupIndex(u32);
123entity_impl!(ModuleInternedRecGroupIndex);
124
125#[repr(transparent)] // Used directly by JIT code.
126#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
127pub struct VMSharedTypeIndex(u32);
128entity_impl!(VMSharedTypeIndex);
129
130impl Default for VMSharedTypeIndex {
131 #[inline]
132 fn default() -> Self {
133 Self(u32::MAX)
134 }
135}
136
137#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
138pub struct RecGroupRelativeTypeIndex(u32);
139entity_impl!(RecGroupRelativeTypeIndex);
140
141/// An index pointing to a type that is canonicalized either within just a `Module` (types start out this way),
142/// an entire `Engine` (required for runtime type checks) or a `RecGroup`
143/// (only used during hash-consing to get a stable representation).
144#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
145pub enum CanonicalizedTypeIndex {
146 /// An index within an engine, therefore canonicalized among all modules
147 /// that can share types with each other.
148 Engine(VMSharedTypeIndex),
149
150 /// An index within the current Wasm module, canonicalized within just this
151 /// current module.
152 Module(ModuleInternedTypeIndex),
153
154 /// An index within the containing type's rec group. This is only used when
155 /// hashing and canonicalizing rec groups, and should never appear outside
156 /// of the engine's type registry.
157 RecGroup(RecGroupRelativeTypeIndex),
158}
159
160impl From<VMSharedTypeIndex> for CanonicalizedTypeIndex {
161 fn from(index: VMSharedTypeIndex) -> Self {
162 Self::Engine(index)
163 }
164}
165impl From<ModuleInternedTypeIndex> for CanonicalizedTypeIndex {
166 fn from(index: ModuleInternedTypeIndex) -> Self {
167 Self::Module(index)
168 }
169}
170impl From<RecGroupRelativeTypeIndex> for CanonicalizedTypeIndex {
171 fn from(index: RecGroupRelativeTypeIndex) -> Self {
172 Self::RecGroup(index)
173 }
174}
175
176impl CanonicalizedTypeIndex {
177 enum_accessors! {
178 e
179 (Module(ModuleInternedTypeIndex) is_module_type_index as_module_type_index unwrap_module_type_index *e)
180 (Engine(VMSharedTypeIndex) is_engine_type_index as_engine_type_index unwrap_engine_type_index *e)
181 (RecGroup(RecGroupRelativeTypeIndex) is_rec_group_type_index as_rec_group_type_index unwrap_rec_group_type_index *e)
182 }
183}