wasmtime/runtime/vm/
export.rs

1#[cfg(feature = "component-model")]
2use crate::runtime::vm::component::VMComponentContext;
3use crate::runtime::vm::vmcontext::{
4    VMContext, VMFuncRef, VMGlobalDefinition, VMGlobalImport, VMGlobalKind, VMMemoryDefinition,
5    VMOpaqueContext, VMTableDefinition, VMTagDefinition,
6};
7use core::ptr::NonNull;
8#[cfg(feature = "component-model")]
9use wasmtime_environ::component::RuntimeComponentInstanceIndex;
10use wasmtime_environ::{
11    DefinedGlobalIndex, DefinedMemoryIndex, DefinedTableIndex, DefinedTagIndex, Global, Memory,
12    Table, Tag,
13};
14
15/// The value of an export passed from one instance to another.
16pub enum Export {
17    /// A function export value.
18    Function(ExportFunction),
19
20    /// A table export value.
21    Table(ExportTable),
22
23    /// A memory export value.
24    Memory(ExportMemory),
25
26    /// A global export value.
27    Global(ExportGlobal),
28
29    /// A tag export value.
30    Tag(ExportTag),
31}
32
33/// A function export value.
34#[derive(Debug, Clone, Copy)]
35pub struct ExportFunction {
36    /// The `VMFuncRef` for this exported function.
37    ///
38    /// Note that exported functions cannot be a null funcref, so this is a
39    /// non-null pointer.
40    pub func_ref: NonNull<VMFuncRef>,
41}
42
43// As part of the contract for using `ExportFunction`, synchronization
44// properties must be upheld. Therefore, despite containing raw pointers,
45// it is declared as Send/Sync.
46unsafe impl Send for ExportFunction {}
47unsafe impl Sync for ExportFunction {}
48
49impl From<ExportFunction> for Export {
50    fn from(func: ExportFunction) -> Export {
51        Export::Function(func)
52    }
53}
54
55/// A table export value.
56#[derive(Debug, Clone)]
57pub struct ExportTable {
58    /// The address of the table descriptor.
59    pub definition: NonNull<VMTableDefinition>,
60    /// Pointer to the containing `VMContext`.
61    pub vmctx: NonNull<VMContext>,
62    /// The table declaration, used for compatibility checking.
63    pub table: Table,
64    /// The index at which the table is defined within the `vmctx`.
65    pub index: DefinedTableIndex,
66}
67
68// See docs on send/sync for `ExportFunction` above.
69unsafe impl Send for ExportTable {}
70unsafe impl Sync for ExportTable {}
71
72impl From<ExportTable> for Export {
73    fn from(func: ExportTable) -> Export {
74        Export::Table(func)
75    }
76}
77
78/// A memory export value.
79#[derive(Debug, Clone)]
80pub struct ExportMemory {
81    /// The address of the memory descriptor.
82    pub definition: NonNull<VMMemoryDefinition>,
83    /// Pointer to the containing `VMContext`.
84    pub vmctx: NonNull<VMContext>,
85    /// The memory declaration, used for compatibility checking.
86    pub memory: Memory,
87    /// The index at which the memory is defined within the `vmctx`.
88    pub index: DefinedMemoryIndex,
89}
90
91// See docs on send/sync for `ExportFunction` above.
92unsafe impl Send for ExportMemory {}
93unsafe impl Sync for ExportMemory {}
94
95impl From<ExportMemory> for Export {
96    fn from(func: ExportMemory) -> Export {
97        Export::Memory(func)
98    }
99}
100
101/// A global export value.
102#[derive(Debug, Clone)]
103pub struct ExportGlobal {
104    /// The address of the global storage.
105    pub definition: NonNull<VMGlobalDefinition>,
106
107    /// Kind of exported global, or what's owning this global and how to find
108    /// it.
109    pub kind: ExportGlobalKind,
110
111    /// The global declaration, used for compatibility checking.
112    pub global: Global,
113}
114
115/// A global export value.
116#[derive(Debug, Clone)]
117pub enum ExportGlobalKind {
118    /// This global was created by the host or embedder and is stored within the
119    /// `Store` at the provided offset.
120    Host(DefinedGlobalIndex),
121
122    /// This global was created as part of a core wasm instance.
123    Instance(NonNull<VMContext>, DefinedGlobalIndex),
124
125    /// This global was created as flags for a component instance.
126    #[cfg(feature = "component-model")]
127    ComponentFlags(NonNull<VMComponentContext>, RuntimeComponentInstanceIndex),
128}
129
130impl ExportGlobal {
131    pub fn from_vmimport(import: &VMGlobalImport, ty: Global) -> ExportGlobal {
132        let kind = match import.kind {
133            VMGlobalKind::Host(index) => ExportGlobalKind::Host(index),
134            VMGlobalKind::Instance(index) => ExportGlobalKind::Instance(
135                unsafe { VMContext::from_opaque(import.vmctx.unwrap().as_non_null()) },
136                index,
137            ),
138            #[cfg(feature = "component-model")]
139            VMGlobalKind::ComponentFlags(index) => ExportGlobalKind::ComponentFlags(
140                unsafe { VMComponentContext::from_opaque(import.vmctx.unwrap().as_non_null()) },
141                index,
142            ),
143        };
144        ExportGlobal {
145            definition: import.from.as_non_null(),
146            kind,
147            global: ty,
148        }
149    }
150
151    pub fn vmimport(&self) -> VMGlobalImport {
152        let (vmctx, kind) = match self.kind {
153            ExportGlobalKind::Host(index) => (None, VMGlobalKind::Host(index)),
154            ExportGlobalKind::Instance(vmctx, index) => (
155                Some(VMOpaqueContext::from_vmcontext(vmctx).into()),
156                VMGlobalKind::Instance(index),
157            ),
158            #[cfg(feature = "component-model")]
159            ExportGlobalKind::ComponentFlags(vmctx, index) => (
160                Some(VMOpaqueContext::from_vmcomponent(vmctx).into()),
161                VMGlobalKind::ComponentFlags(index),
162            ),
163        };
164        VMGlobalImport {
165            from: self.definition.into(),
166            vmctx,
167            kind,
168        }
169    }
170}
171
172// See docs on send/sync for `ExportFunction` above.
173unsafe impl Send for ExportGlobal {}
174unsafe impl Sync for ExportGlobal {}
175
176impl From<ExportGlobal> for Export {
177    fn from(func: ExportGlobal) -> Export {
178        Export::Global(func)
179    }
180}
181
182/// A tag export value.
183#[derive(Debug, Clone)]
184pub struct ExportTag {
185    /// The address of the global storage.
186    pub definition: NonNull<VMTagDefinition>,
187    /// The instance that owns this tag.
188    pub vmctx: NonNull<VMContext>,
189    /// The global declaration, used for compatibility checking.
190    pub tag: Tag,
191    /// The index at which the tag is defined within the `vmctx`.
192    pub index: DefinedTagIndex,
193}
194
195// See docs on send/sync for `ExportFunction` above.
196unsafe impl Send for ExportTag {}
197unsafe impl Sync for ExportTag {}
198
199impl From<ExportTag> for Export {
200    fn from(func: ExportTag) -> Export {
201        Export::Tag(func)
202    }
203}