Skip to content

Commit 09662fa

Browse files
Fix module-linking handling of instance subtypes (#2466)
* Fix module-linking handling of instance subtypes When we alias the nth export of an instance, due to subtyping the nth export may not actually be what we want. Instead we need to look at our local type definition's nth export's name, and lookup that name off the export. * Update crates/wasmtime/src/instance.rs Co-authored-by: Peter Huene <peter@huene.dev> Co-authored-by: Peter Huene <peter@huene.dev>
1 parent 111f6dc commit 09662fa

2 files changed

Lines changed: 63 additions & 3 deletions

File tree

crates/wasmtime/src/instance.rs

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,18 +82,29 @@ fn instantiate(
8282
imports.modules.push(module.submodule(*idx));
8383
}
8484

85-
// Here we lookup our instance handle, ask it for the nth export,
85+
// Here we lookup our instance handle, find the right export,
8686
// and then push that item into our own index space. We eschew
8787
// type-checking since only valid modules reach this point.
8888
//
89+
// Note that export lookup here needs to happen by name. The
90+
// `export` index is an index into our local type definition of the
91+
// type of the instance to figure out what name it was assigned.
92+
// This is where the subtyping happens!
93+
//
8994
// Note that the unsafety here is because we're asserting that the
9095
// handle comes from our same store, but this should be true because
9196
// we acquired the handle from an instance in the store.
9297
Initializer::AliasInstanceExport { instance, export } => {
98+
let instance_ty = env_module.instances[*instance];
99+
let export_name = module.types().instance_signatures[instance_ty]
100+
.exports
101+
.get_index(*export)
102+
.expect("validation bug - should be valid")
103+
.0;
93104
let handle = &imports.instances[*instance];
94-
let export_index = &handle.module().exports[*export];
105+
let entity_index = &handle.module().exports[export_name];
95106
let item = Extern::from_wasmtime_export(
96-
handle.lookup_by_declaration(export_index),
107+
handle.lookup_by_declaration(entity_index),
97108
unsafe { store.existing_instance_handle(handle.clone()) },
98109
);
99110
imports.push_extern(&item);

tests/misc_testsuite/module-linking/instantiate.wast

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,3 +233,52 @@
233233
(import "b" "i" (instance (export "" (func))))
234234
)
235235
"instance types incompatible")
236+
237+
;; ensure we ignore other exported items
238+
(module $b
239+
(module $m
240+
(func (export "f") (result i32)
241+
i32.const 300)
242+
(global (export "g") i32 (i32.const 0xfeed))
243+
)
244+
245+
(instance (export "i") (instantiate 0))
246+
)
247+
(module
248+
(import "b" "i" (instance $i
249+
(export "g" (global $g i32))
250+
))
251+
252+
(func (export "get") (result i32)
253+
global.get $i.$g)
254+
)
255+
(assert_return (invoke "get") (i32.const 0xfeed))
256+
257+
;; ensure the right export is used even when subtyping comes into play
258+
(module $b
259+
(module $m
260+
(func (export "f") (result i32)
261+
i32.const 300)
262+
(func (export "g") (param i32) (result i32)
263+
i32.const 100
264+
local.get 0
265+
i32.add)
266+
)
267+
268+
(instance (export "i") (instantiate 0))
269+
)
270+
(module
271+
(import "b" "i" (instance $i
272+
;; notice that this order is swapped
273+
(export "g" (func $g (param i32) (result i32)))
274+
(export "f" (func $f (result i32)))
275+
))
276+
277+
(func (export "f") (result i32)
278+
call $i.$f)
279+
(func (export "g") (param i32) (result i32)
280+
local.get 0
281+
call $i.$g)
282+
)
283+
(assert_return (invoke "f") (i32.const 300))
284+
(assert_return (invoke "g" (i32.const 3000)) (i32.const 3100))

0 commit comments

Comments
 (0)