Skip to content

Commit 751e2f6

Browse files
authored
Try #1837:
2 parents 6041c03 + 7973a96 commit 751e2f6

File tree

16 files changed

+646
-316
lines changed

16 files changed

+646
-316
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
### Added
1111

12+
- [#1837](https://github.com/wasmerio/wasmer/pull/1837) It is now possible to use exports of an `Intance` even after the `Instance` has been freed
1213
- [#1831](https://github.com/wasmerio/wasmer/pull/1831) Added support for Apple Silicon chips (`arm64-apple-darwin`)
1314
- [#1649](https://github.com/wasmerio/wasmer/pull/1649) Add outline of migration to 1.0.0 docs.
1415

lib/api/src/externals/function.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ impl Function {
110110
vmctx,
111111
signature: ty.clone(),
112112
call_trampoline: None,
113+
instance_allocator: None,
113114
},
114115
},
115116
}
@@ -172,6 +173,7 @@ impl Function {
172173
vmctx,
173174
signature: ty.clone(),
174175
call_trampoline: None,
176+
instance_allocator: None,
175177
},
176178
},
177179
}
@@ -225,6 +227,7 @@ impl Function {
225227
signature,
226228
kind: VMFunctionKind::Static,
227229
call_trampoline: None,
230+
instance_allocator: None,
228231
},
229232
},
230233
}
@@ -294,6 +297,7 @@ impl Function {
294297
vmctx,
295298
signature,
296299
call_trampoline: None,
300+
instance_allocator: None,
297301
},
298302
},
299303
}
@@ -346,6 +350,7 @@ impl Function {
346350
vmctx,
347351
signature,
348352
call_trampoline: None,
353+
instance_allocator: None,
349354
},
350355
},
351356
}
@@ -528,7 +533,7 @@ impl Function {
528533
Ok(results.into_boxed_slice())
529534
}
530535

531-
pub(crate) fn from_export(store: &Store, wasmer_export: ExportFunction) -> Self {
536+
pub(crate) fn from_vm_export(store: &Store, wasmer_export: ExportFunction) -> Self {
532537
if let Some(trampoline) = wasmer_export.vm_function.call_trampoline {
533538
Self {
534539
store: store.clone(),

lib/api/src/externals/global.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ impl Global {
181181
Ok(())
182182
}
183183

184-
pub(crate) fn from_export(store: &Store, wasmer_export: ExportGlobal) -> Self {
184+
pub(crate) fn from_vm_export(store: &Store, wasmer_export: ExportGlobal) -> Self {
185185
Self {
186186
store: store.clone(),
187187
global: wasmer_export.vm_global.from,
@@ -220,6 +220,7 @@ impl<'a> Exportable<'a> for Global {
220220
ExportGlobal {
221221
vm_global: VMExportGlobal {
222222
from: self.global.clone(),
223+
instance_allocator: None,
223224
},
224225
}
225226
.into()

lib/api/src/externals/memory.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ impl Memory {
221221
unsafe { MemoryView::new(base as _, length as u32) }
222222
}
223223

224-
pub(crate) fn from_export(store: &Store, wasmer_export: ExportMemory) -> Self {
224+
pub(crate) fn from_vm_export(store: &Store, wasmer_export: ExportMemory) -> Self {
225225
Self {
226226
store: store.clone(),
227227
memory: wasmer_export.vm_memory.from,
@@ -250,6 +250,7 @@ impl<'a> Exportable<'a> for Memory {
250250
ExportMemory {
251251
vm_memory: VMExportMemory {
252252
from: self.memory.clone(),
253+
instance_allocator: None,
253254
},
254255
}
255256
.into()

lib/api/src/externals/mod.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -46,13 +46,13 @@ impl Extern {
4646
}
4747
}
4848

49-
/// Create an `Extern` from an `Export`.
50-
pub fn from_export(store: &Store, export: Export) -> Self {
49+
/// Create an `Extern` from an `wasmer_vm::Export`.
50+
pub fn from_vm_export(store: &Store, export: Export) -> Self {
5151
match export {
52-
Export::Function(f) => Self::Function(Function::from_export(store, f)),
53-
Export::Memory(m) => Self::Memory(Memory::from_export(store, m)),
54-
Export::Global(g) => Self::Global(Global::from_export(store, g)),
55-
Export::Table(t) => Self::Table(Table::from_export(store, t)),
52+
Export::Function(f) => Self::Function(Function::from_vm_export(store, f)),
53+
Export::Memory(m) => Self::Memory(Memory::from_vm_export(store, m)),
54+
Export::Global(g) => Self::Global(Global::from_vm_export(store, g)),
55+
Export::Table(t) => Self::Table(Table::from_vm_export(store, t)),
5656
}
5757
}
5858
}

lib/api/src/externals/table.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ impl Table {
140140
Ok(())
141141
}
142142

143-
pub(crate) fn from_export(store: &Store, wasmer_export: ExportTable) -> Self {
143+
pub(crate) fn from_vm_export(store: &Store, wasmer_export: ExportTable) -> Self {
144144
Self {
145145
store: store.clone(),
146146
table: wasmer_export.vm_table.from,
@@ -158,6 +158,7 @@ impl<'a> Exportable<'a> for Table {
158158
ExportTable {
159159
vm_table: VMExportTable {
160160
from: self.table.clone(),
161+
instance_allocator: None,
161162
},
162163
}
163164
.into()

lib/api/src/instance.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ impl Instance {
119119
.map(|export| {
120120
let name = export.name().to_string();
121121
let export = handle.lookup(&name).expect("export");
122-
let extern_ = Extern::from_export(store, export.into());
122+
let extern_ = Extern::from_vm_export(store, export.into());
123123
(name, extern_)
124124
})
125125
.collect::<Exports>();

lib/api/src/native.rs

+3
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ where
7373
signature,
7474
kind: other.arg_kind,
7575
call_trampoline: None,
76+
instance_allocator: None,
7677
}
7778
}
7879
}*/
@@ -93,6 +94,7 @@ where
9394
signature,
9495
kind: other.arg_kind,
9596
call_trampoline: None,
97+
instance_allocator: None,
9698
},
9799
}
98100
}
@@ -117,6 +119,7 @@ where
117119
signature,
118120
kind: other.arg_kind,
119121
call_trampoline: None,
122+
instance_allocator: None,
120123
},
121124
},
122125
}

lib/api/src/types.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -85,9 +85,10 @@ impl ValFuncRef for Val {
8585
kind: wasmer_vm::VMFunctionKind::Static,
8686
vmctx: item.vmctx,
8787
call_trampoline: None,
88+
instance_allocator: None,
8889
},
8990
};
90-
let f = Function::from_export(store, export);
91+
let f = Function::from_vm_export(store, export);
9192
Self::FuncRef(f)
9293
}
9394
}

lib/api/tests/instance.rs

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
use anyhow::Result;
2+
use wasmer::*;
3+
4+
#[test]
5+
fn exports_work_after_multiple_instances_have_been_freed() -> Result<()> {
6+
let store = Store::default();
7+
let module = Module::new(
8+
&store,
9+
"
10+
(module
11+
(type $sum_t (func (param i32 i32) (result i32)))
12+
(func $sum_f (type $sum_t) (param $x i32) (param $y i32) (result i32)
13+
local.get $x
14+
local.get $y
15+
i32.add)
16+
(export \"sum\" (func $sum_f)))
17+
",
18+
)?;
19+
20+
let import_object = ImportObject::new();
21+
let instance = Instance::new(&module, &import_object)?;
22+
let instance2 = instance.clone();
23+
let instance3 = instance.clone();
24+
25+
// The function is cloned to “break” the connection with `instance`.
26+
let sum = instance.exports.get_function("sum")?.clone();
27+
28+
drop(instance);
29+
drop(instance2);
30+
drop(instance3);
31+
32+
// All instances have been dropped, but `sum` continues to work!
33+
assert_eq!(
34+
sum.call(&[Value::I32(1), Value::I32(2)])?.into_vec(),
35+
vec![Value::I32(3)],
36+
);
37+
38+
Ok(())
39+
}

lib/c-api/src/wasm_c_api/wasi/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -345,7 +345,7 @@ unsafe fn wasi_get_imports_inner(
345345
import_type.name()
346346
),
347347
}));
348-
let inner = Extern::from_export(store, export);
348+
let inner = Extern::from_vm_export(store, export);
349349

350350
Some(Box::new(wasm_extern_t {
351351
instance: None,

lib/deprecated/runtime-core/src/module.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -163,12 +163,12 @@ impl Module {
163163

164164
(
165165
(namespace, name),
166-
new::wasmer::Extern::from_export(store, Export::Function(function)),
166+
new::wasmer::Extern::from_vm_export(store, Export::Function(function)),
167167
)
168168
}
169169
export => (
170170
(namespace, name),
171-
new::wasmer::Extern::from_export(store, export),
171+
new::wasmer::Extern::from_vm_export(store, export),
172172
),
173173
})
174174
.for_each(|((namespace, name), extern_)| {

lib/vm/src/export.rs

+31-3
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// Attributions: https://github.com/wasmerio/wasmer/blob/master/ATTRIBUTIONS.md
33

44
use crate::global::Global;
5+
use crate::instance::InstanceAllocator;
56
use crate::memory::{Memory, MemoryStyle};
67
use crate::table::{Table, TableStyle};
78
use crate::vmcontext::{VMFunctionBody, VMFunctionEnvironment, VMFunctionKind, VMTrampoline};
@@ -29,15 +30,27 @@ pub enum VMExport {
2930
pub struct VMExportFunction {
3031
/// The address of the native-code function.
3132
pub address: *const VMFunctionBody,
33+
3234
/// Pointer to the containing `VMContext`.
3335
pub vmctx: VMFunctionEnvironment,
36+
3437
/// The function type, used for compatibility checking.
3538
pub signature: FunctionType,
36-
/// The function kind (specifies the calling convention for the function).
39+
40+
/// The function kind (specifies the calling convention for the
41+
/// function).
3742
pub kind: VMFunctionKind,
38-
/// Address of the function call trampoline owned by the same VMContext that owns the VMFunctionBody.
39-
/// May be None when the function is a host-function (FunctionType == Dynamic or vmctx == nullptr).
43+
44+
/// Address of the function call trampoline owned by the same
45+
/// VMContext that owns the VMFunctionBody.
46+
///
47+
/// May be `None` when the function is a host function (`FunctionType`
48+
/// == `Dynamic` or `vmctx` == `nullptr`).
4049
pub call_trampoline: Option<VMTrampoline>,
50+
51+
/// A “reference” to the instance through the
52+
/// `InstanceAllocator`. `None` if it is a host function.
53+
pub instance_allocator: Option<InstanceAllocator>,
4154
}
4255

4356
/// # Safety
@@ -59,13 +72,18 @@ impl From<VMExportFunction> for VMExport {
5972
pub struct VMExportTable {
6073
/// Pointer to the containing `Table`.
6174
pub from: Arc<dyn Table>,
75+
76+
/// A “reference” to the instance through the
77+
/// `InstanceAllocator`. `None` if it is a host function.
78+
pub instance_allocator: Option<InstanceAllocator>,
6279
}
6380

6481
/// # Safety
6582
/// This is correct because there is no non-threadsafe logic directly in this type;
6683
/// correct use of the raw table from multiple threads via `definition` requires `unsafe`
6784
/// and is the responsibilty of the user of this type.
6885
unsafe impl Send for VMExportTable {}
86+
6987
/// # Safety
7088
/// This is correct because the values directly in `definition` should be considered immutable
7189
/// and the type is both `Send` and `Clone` (thus marking it `Sync` adds no new behavior, it
@@ -100,13 +118,18 @@ impl From<VMExportTable> for VMExport {
100118
pub struct VMExportMemory {
101119
/// Pointer to the containing `Memory`.
102120
pub from: Arc<dyn Memory>,
121+
122+
/// A “reference” to the instance through the
123+
/// `InstanceAllocator`. `None` if it is a host function.
124+
pub instance_allocator: Option<InstanceAllocator>,
103125
}
104126

105127
/// # Safety
106128
/// This is correct because there is no non-threadsafe logic directly in this type;
107129
/// correct use of the raw memory from multiple threads via `definition` requires `unsafe`
108130
/// and is the responsibilty of the user of this type.
109131
unsafe impl Send for VMExportMemory {}
132+
110133
/// # Safety
111134
/// This is correct because the values directly in `definition` should be considered immutable
112135
/// and the type is both `Send` and `Clone` (thus marking it `Sync` adds no new behavior, it
@@ -141,13 +164,18 @@ impl From<VMExportMemory> for VMExport {
141164
pub struct VMExportGlobal {
142165
/// The global declaration, used for compatibility checking.
143166
pub from: Arc<Global>,
167+
168+
/// A “reference” to the instance through the
169+
/// `InstanceAllocator`. `None` if it is a host function.
170+
pub instance_allocator: Option<InstanceAllocator>,
144171
}
145172

146173
/// # Safety
147174
/// This is correct because there is no non-threadsafe logic directly in this type;
148175
/// correct use of the raw global from multiple threads via `definition` requires `unsafe`
149176
/// and is the responsibilty of the user of this type.
150177
unsafe impl Send for VMExportGlobal {}
178+
151179
/// # Safety
152180
/// This is correct because the values directly in `definition` should be considered immutable
153181
/// from the perspective of users of this type and the type is both `Send` and `Clone` (thus

0 commit comments

Comments
 (0)