1pub(crate) use self::builder::InstanceEntityBuilder;
2pub use self::exports::{Export, ExportsIter, Extern, ExternType};
3use super::{
4 engine::DedupFuncType,
5 AsContext,
6 Func,
7 Global,
8 Memory,
9 Module,
10 StoreContext,
11 Stored,
12 Table,
13};
14use crate::{
15 func::FuncError,
16 memory::DataSegment,
17 ElementSegment,
18 Error,
19 TypedFunc,
20 WasmParams,
21 WasmResults,
22};
23use alloc::{boxed::Box, collections::BTreeMap, sync::Arc};
24use wasmi_arena::ArenaIndex;
25
26mod builder;
27mod exports;
28
29#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
31pub struct InstanceIdx(u32);
32
33impl ArenaIndex for InstanceIdx {
34 fn into_usize(self) -> usize {
35 self.0 as usize
36 }
37
38 fn from_usize(value: usize) -> Self {
39 let value = value.try_into().unwrap_or_else(|error| {
40 panic!("index {value} is out of bounds as instance index: {error}")
41 });
42 Self(value)
43 }
44}
45
46#[derive(Debug)]
48pub struct InstanceEntity {
49 initialized: bool,
50 func_types: Arc<[DedupFuncType]>,
51 tables: Box<[Table]>,
52 funcs: Box<[Func]>,
53 memories: Box<[Memory]>,
54 globals: Box<[Global]>,
55 exports: BTreeMap<Box<str>, Extern>,
56 data_segments: Box<[DataSegment]>,
57 elem_segments: Box<[ElementSegment]>,
58}
59
60impl InstanceEntity {
61 pub fn uninitialized() -> InstanceEntity {
63 Self {
64 initialized: false,
65 func_types: Arc::new([]),
66 tables: [].into(),
67 funcs: [].into(),
68 memories: [].into(),
69 globals: [].into(),
70 exports: BTreeMap::new(),
71 data_segments: [].into(),
72 elem_segments: [].into(),
73 }
74 }
75
76 pub fn build(module: &Module) -> InstanceEntityBuilder {
78 InstanceEntityBuilder::new(module)
79 }
80
81 pub fn is_initialized(&self) -> bool {
83 self.initialized
84 }
85
86 pub fn get_memory(&self, index: u32) -> Option<Memory> {
88 self.memories.get(index as usize).copied()
89 }
90
91 pub fn get_table(&self, index: u32) -> Option<Table> {
93 self.tables.get(index as usize).copied()
94 }
95
96 pub fn get_global(&self, index: u32) -> Option<Global> {
98 self.globals.get(index as usize).copied()
99 }
100
101 pub fn get_func(&self, index: u32) -> Option<Func> {
103 self.funcs.get(index as usize).copied()
104 }
105
106 pub fn get_signature(&self, index: u32) -> Option<&DedupFuncType> {
108 self.func_types.get(index as usize)
109 }
110
111 pub fn get_data_segment(&self, index: u32) -> Option<DataSegment> {
113 self.data_segments.get(index as usize).copied()
114 }
115
116 pub fn get_element_segment(&self, index: u32) -> Option<ElementSegment> {
118 self.elem_segments.get(index as usize).copied()
119 }
120
121 pub fn get_export(&self, name: &str) -> Option<Extern> {
123 self.exports.get(name).copied()
124 }
125
126 pub fn exports(&self) -> ExportsIter {
130 ExportsIter::new(self.exports.iter())
131 }
132}
133
134#[derive(Debug, Copy, Clone, PartialEq, Eq)]
146#[repr(transparent)]
147pub struct Instance(Stored<InstanceIdx>);
148
149impl Instance {
150 pub(super) fn from_inner(stored: Stored<InstanceIdx>) -> Self {
158 Self(stored)
159 }
160
161 pub(super) fn as_inner(&self) -> &Stored<InstanceIdx> {
163 &self.0
164 }
165
166 pub(crate) fn get_func_by_index(&self, store: impl AsContext, index: u32) -> Option<Func> {
172 store
173 .as_context()
174 .store
175 .inner
176 .resolve_instance(self)
177 .get_func(index)
178 }
179
180 pub fn get_export(&self, store: impl AsContext, name: &str) -> Option<Extern> {
186 store
187 .as_context()
188 .store
189 .inner
190 .resolve_instance(self)
191 .get_export(name)
192 }
193
194 pub fn get_func(&self, store: impl AsContext, name: &str) -> Option<Func> {
203 self.get_export(store, name)?.into_func()
204 }
205
206 pub fn get_typed_func<Params, Results>(
221 &self,
222 store: impl AsContext,
223 name: &str,
224 ) -> Result<TypedFunc<Params, Results>, Error>
225 where
226 Params: WasmParams,
227 Results: WasmResults,
228 {
229 self.get_export(&store, name)
230 .and_then(Extern::into_func)
231 .ok_or_else(|| Error::Func(FuncError::ExportedFuncNotFound))?
232 .typed::<Params, Results>(store)
233 }
234
235 pub fn get_global(&self, store: impl AsContext, name: &str) -> Option<Global> {
244 self.get_export(store, name)?.into_global()
245 }
246
247 pub fn get_table(&self, store: impl AsContext, name: &str) -> Option<Table> {
256 self.get_export(store, name)?.into_table()
257 }
258
259 pub fn get_memory(&self, store: impl AsContext, name: &str) -> Option<Memory> {
268 self.get_export(store, name)?.into_memory()
269 }
270
271 pub fn exports<'ctx, T: 'ctx>(
279 &self,
280 store: impl Into<StoreContext<'ctx, T>>,
281 ) -> ExportsIter<'ctx> {
282 store.into().store.inner.resolve_instance(self).exports()
283 }
284}