1 #[cfg(feature = "component-model")] 2 use crate::runtime::vm::component::VMComponentContext; 3 use crate::runtime::vm::vmcontext::{ 4 VMContext, VMFuncRef, VMGlobalDefinition, VMGlobalImport, VMGlobalKind, VMMemoryDefinition, 5 VMOpaqueContext, VMTableDefinition, VMTagDefinition, 6 }; 7 use core::ptr::NonNull; 8 #[cfg(feature = "component-model")] 9 use wasmtime_environ::component::RuntimeComponentInstanceIndex; 10 use 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. 16 pub 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)] 35 pub 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. 46 unsafe impl Send for ExportFunction {} 47 unsafe impl Sync for ExportFunction {} 48 49 impl 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)] 57 pub 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. 69 unsafe impl Send for ExportTable {} 70 unsafe impl Sync for ExportTable {} 71 72 impl 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)] 80 pub 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. 92 unsafe impl Send for ExportMemory {} 93 unsafe impl Sync for ExportMemory {} 94 95 impl 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)] 103 pub 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)] 117 pub 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 130 impl 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. 173 unsafe impl Send for ExportGlobal {} 174 unsafe impl Sync for ExportGlobal {} 175 176 impl 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)] 184 pub 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. 196 unsafe impl Send for ExportTag {} 197 unsafe impl Sync for ExportTag {} 198 199 impl From<ExportTag> for Export { 200 fn from(func: ExportTag) -> Export { 201 Export::Tag(func) 202 } 203 } 204