Skip to content

Commit 7649c22

Browse files
committed
allow importing the same function sync and async
Signed-off-by: Joel Dice <[email protected]>
1 parent c9694e6 commit 7649c22

File tree

4 files changed

+94
-44
lines changed

4 files changed

+94
-44
lines changed

crates/wit-component/src/encoding.rs

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -493,7 +493,13 @@ impl<'a> EncodingState<'a> {
493493
// Next encode all required functions from this imported interface
494494
// into the instance type.
495495
for (_, func) in interface.functions.iter() {
496-
if !info.lowerings.contains_key(&func.name) {
496+
if !(info
497+
.lowerings
498+
.contains_key(&(func.name.clone(), AbiVariant::GuestImport))
499+
|| info
500+
.lowerings
501+
.contains_key(&(func.name.clone(), AbiVariant::GuestImportAsync)))
502+
{
497503
continue;
498504
}
499505
log::trace!("encoding function type for `{}`", func.name);
@@ -526,7 +532,13 @@ impl<'a> EncodingState<'a> {
526532
WorldItem::Interface { .. } | WorldItem::Type(_) => continue,
527533
};
528534
let name = resolve.name_world_key(name);
529-
if !info.lowerings.contains_key(&name) {
535+
if !(info
536+
.lowerings
537+
.contains_key(&(name.clone(), AbiVariant::GuestImport))
538+
|| info
539+
.lowerings
540+
.contains_key(&(name.clone(), AbiVariant::GuestImportAsync)))
541+
{
530542
continue;
531543
}
532544
log::trace!("encoding function type for `{}`", func.name);
@@ -1214,7 +1226,7 @@ impl<'a> EncodingState<'a> {
12141226
encoding,
12151227
} => {
12161228
let interface = &self.info.import_map[interface];
1217-
let (name, _) = interface.lowerings.get_index(*index).unwrap();
1229+
let ((name, _), _) = interface.lowerings.get_index(*index).unwrap();
12181230
let func_index = match &interface.interface {
12191231
Some(interface_id) => {
12201232
let instance_index = self.imported_instances[interface_id];
@@ -1880,7 +1892,7 @@ impl<'a> EncodingState<'a> {
18801892
};
18811893

18821894
let import = &self.info.import_map[&interface_key];
1883-
let (index, _, lowering) = import.lowerings.get_full(name).unwrap();
1895+
let (index, _, lowering) = import.lowerings.get_full(&(name.clone(), abi)).unwrap();
18841896
let metadata = self.info.module_metadata_for(for_module);
18851897

18861898
let index = match lowering {
@@ -2200,7 +2212,7 @@ impl<'a> Shims<'a> {
22002212
};
22012213

22022214
for (module, field, import) in module_imports.imports() {
2203-
let (key, name, interface_key) = match import {
2215+
let (key, name, interface_key, abi) = match import {
22042216
// These imports don't require shims, they can be satisfied
22052217
// as-needed when required.
22062218
Import::ImportedResourceDrop(..)
@@ -2388,13 +2400,13 @@ impl<'a> Shims<'a> {
23882400
// WIT-level functions may require an indirection, so yield some
23892401
// metadata out of this `match` to the loop below to figure that
23902402
// out.
2391-
Import::InterfaceFunc(key, _, name, _) => {
2392-
(key, name, Some(resolve.name_world_key(key)))
2403+
Import::InterfaceFunc(key, _, name, abi) => {
2404+
(key, name, Some(resolve.name_world_key(key)), *abi)
23932405
}
2394-
Import::WorldFunc(key, name, _) => (key, name, None),
2406+
Import::WorldFunc(key, name, abi) => (key, name, None, *abi),
23952407
};
23962408
let interface = &world.import_map[&interface_key];
2397-
let (index, _, lowering) = interface.lowerings.get_full(name).unwrap();
2409+
let (index, _, lowering) = interface.lowerings.get_full(&(name.clone(), abi)).unwrap();
23982410
let shim_name = self.shims.len().to_string();
23992411
match lowering {
24002412
Lowering::Direct | Lowering::ResourceDrop(_) => {}

crates/wit-component/src/encoding/world.rs

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ pub struct ComponentWorld<'a> {
4747

4848
#[derive(Debug)]
4949
pub struct ImportedInterface {
50-
pub lowerings: IndexMap<String, Lowering>,
50+
pub lowerings: IndexMap<(String, AbiVariant), Lowering>,
5151
pub interface: Option<InterfaceId>,
5252
}
5353

@@ -420,26 +420,28 @@ struct Required<'a> {
420420

421421
impl ImportedInterface {
422422
fn add_func(&mut self, required: &Required<'_>, resolve: &Resolve, func: &Function) {
423-
let abi = match required.interface_funcs.get(&self.interface) {
424-
Some(set) if set.contains(&(func.name.as_str(), AbiVariant::GuestImport)) => {
425-
AbiVariant::GuestImport
423+
let mut abis = Vec::with_capacity(2);
424+
if let Some(set) = required.interface_funcs.get(&self.interface) {
425+
if set.contains(&(func.name.as_str(), AbiVariant::GuestImport)) {
426+
abis.push(AbiVariant::GuestImport);
426427
}
427-
Some(set) if set.contains(&(func.name.as_str(), AbiVariant::GuestImportAsync)) => {
428-
AbiVariant::GuestImportAsync
428+
if set.contains(&(func.name.as_str(), AbiVariant::GuestImportAsync)) {
429+
abis.push(AbiVariant::GuestImportAsync);
429430
}
430-
_ => return,
431-
};
432-
log::trace!("add func {}", func.name);
433-
let options = RequiredOptions::for_import(resolve, func, abi);
434-
let lowering = if options.is_empty() {
435-
Lowering::Direct
436-
} else {
437-
let sig = resolve.wasm_signature(abi, func);
438-
Lowering::Indirect { sig, options }
439-
};
431+
}
432+
for abi in abis {
433+
log::trace!("add func {} {abi:?}", func.name);
434+
let options = RequiredOptions::for_import(resolve, func, abi);
435+
let lowering = if options.is_empty() {
436+
Lowering::Direct
437+
} else {
438+
let sig = resolve.wasm_signature(abi, func);
439+
Lowering::Indirect { sig, options }
440+
};
440441

441-
let prev = self.lowerings.insert(func.name.clone(), lowering);
442-
assert!(prev.is_none());
442+
let prev = self.lowerings.insert((func.name.clone(), abi), lowering);
443+
assert!(prev.is_none());
444+
}
443445
}
444446

445447
fn add_type(&mut self, required: &Required<'_>, resolve: &Resolve, id: TypeId) {
@@ -452,7 +454,9 @@ impl ImportedInterface {
452454

453455
if required.resource_drops.contains(&id) {
454456
let name = format!("{name}_drop");
455-
let prev = self.lowerings.insert(name, Lowering::ResourceDrop(id));
457+
let prev = self
458+
.lowerings
459+
.insert((name, AbiVariant::GuestImport), Lowering::ResourceDrop(id));
456460
assert!(prev.is_none());
457461
}
458462
}

crates/wit-component/tests/components/async-import/component.wat

Lines changed: 48 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,16 @@
1010
(import "foo" (func (;0;) (type 1)))
1111
(core module (;0;)
1212
(type (;0;) (func (param i32 i32) (result i32)))
13-
(type (;1;) (func (param i32 i32 i32 i32) (result i32)))
13+
(type (;1;) (func (param i32 i32 i32)))
14+
(type (;2;) (func (param i32 i32 i32 i32) (result i32)))
1415
(import "$root" "[async]foo" (func (;0;) (type 0)))
1516
(import "foo:foo/bar" "[async]foo" (func (;1;) (type 0)))
17+
(import "$root" "foo" (func (;2;) (type 1)))
18+
(import "foo:foo/bar" "foo" (func (;3;) (type 1)))
1619
(memory (;0;) 1)
1720
(export "memory" (memory 0))
18-
(export "cabi_realloc" (func 2))
19-
(func (;2;) (type 1) (param i32 i32 i32 i32) (result i32)
21+
(export "cabi_realloc" (func 4))
22+
(func (;4;) (type 2) (param i32 i32 i32 i32) (result i32)
2023
unreachable
2124
)
2225
(@producers
@@ -26,44 +29,68 @@
2629
)
2730
(core module (;1;)
2831
(type (;0;) (func (param i32 i32) (result i32)))
29-
(table (;0;) 2 2 funcref)
32+
(type (;1;) (func (param i32 i32 i32)))
33+
(table (;0;) 4 4 funcref)
3034
(export "0" (func $"indirect-$root-[async]foo"))
31-
(export "1" (func $"indirect-foo:foo/bar-[async]foo"))
35+
(export "1" (func $indirect-$root-foo))
36+
(export "2" (func $"indirect-foo:foo/bar-[async]foo"))
37+
(export "3" (func $indirect-foo:foo/bar-foo))
3238
(export "$imports" (table 0))
3339
(func $"indirect-$root-[async]foo" (;0;) (type 0) (param i32 i32) (result i32)
3440
local.get 0
3541
local.get 1
3642
i32.const 0
3743
call_indirect (type 0)
3844
)
39-
(func $"indirect-foo:foo/bar-[async]foo" (;1;) (type 0) (param i32 i32) (result i32)
45+
(func $indirect-$root-foo (;1;) (type 1) (param i32 i32 i32)
4046
local.get 0
4147
local.get 1
48+
local.get 2
4249
i32.const 1
50+
call_indirect (type 1)
51+
)
52+
(func $"indirect-foo:foo/bar-[async]foo" (;2;) (type 0) (param i32 i32) (result i32)
53+
local.get 0
54+
local.get 1
55+
i32.const 2
4356
call_indirect (type 0)
4457
)
58+
(func $indirect-foo:foo/bar-foo (;3;) (type 1) (param i32 i32 i32)
59+
local.get 0
60+
local.get 1
61+
local.get 2
62+
i32.const 3
63+
call_indirect (type 1)
64+
)
4565
(@producers
4666
(processed-by "wit-component" "$CARGO_PKG_VERSION")
4767
)
4868
)
4969
(core module (;2;)
5070
(type (;0;) (func (param i32 i32) (result i32)))
71+
(type (;1;) (func (param i32 i32 i32)))
5172
(import "" "0" (func (;0;) (type 0)))
52-
(import "" "1" (func (;1;) (type 0)))
53-
(import "" "$imports" (table (;0;) 2 2 funcref))
54-
(elem (;0;) (i32.const 0) func 0 1)
73+
(import "" "1" (func (;1;) (type 1)))
74+
(import "" "2" (func (;2;) (type 0)))
75+
(import "" "3" (func (;3;) (type 1)))
76+
(import "" "$imports" (table (;0;) 4 4 funcref))
77+
(elem (;0;) (i32.const 0) func 0 1 2 3)
5578
(@producers
5679
(processed-by "wit-component" "$CARGO_PKG_VERSION")
5780
)
5881
)
5982
(core instance (;0;) (instantiate 1))
6083
(alias core export 0 "0" (core func (;0;)))
84+
(alias core export 0 "1" (core func (;1;)))
6185
(core instance (;1;)
6286
(export "[async]foo" (func 0))
87+
(export "foo" (func 1))
6388
)
64-
(alias core export 0 "1" (core func (;1;)))
89+
(alias core export 0 "2" (core func (;2;)))
90+
(alias core export 0 "3" (core func (;3;)))
6591
(core instance (;2;)
66-
(export "[async]foo" (func 1))
92+
(export "[async]foo" (func 2))
93+
(export "foo" (func 3))
6794
)
6895
(core instance (;3;) (instantiate 0
6996
(with "$root" (instance 1))
@@ -72,14 +99,19 @@
7299
)
73100
(alias core export 3 "memory" (core memory (;0;)))
74101
(alias core export 0 "$imports" (core table (;0;)))
75-
(alias core export 3 "cabi_realloc" (core func (;2;)))
76-
(core func (;3;) (canon lower (func 0) (memory 0) (realloc 2) string-encoding=utf8 async))
102+
(alias core export 3 "cabi_realloc" (core func (;4;)))
103+
(core func (;5;) (canon lower (func 0) (memory 0) (realloc 4) string-encoding=utf8 async))
104+
(core func (;6;) (canon lower (func 0) (memory 0) (realloc 4) string-encoding=utf8))
77105
(alias export 0 "foo" (func (;1;)))
78-
(core func (;4;) (canon lower (func 1) (memory 0) (realloc 2) string-encoding=utf8 async))
106+
(core func (;7;) (canon lower (func 1) (memory 0) (realloc 4) string-encoding=utf8 async))
107+
(alias export 0 "foo" (func (;2;)))
108+
(core func (;8;) (canon lower (func 2) (memory 0) (realloc 4) string-encoding=utf8))
79109
(core instance (;4;)
80110
(export "$imports" (table 0))
81-
(export "0" (func 3))
82-
(export "1" (func 4))
111+
(export "0" (func 5))
112+
(export "1" (func 6))
113+
(export "2" (func 7))
114+
(export "3" (func 8))
83115
)
84116
(core instance (;5;) (instantiate 2
85117
(with "" (instance 4))
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
(module
22
(func (import "$root" "[async]foo") (param i32 i32) (result i32))
33
(func (import "foo:foo/bar" "[async]foo") (param i32 i32) (result i32))
4+
(func (import "$root" "foo") (param i32 i32 i32))
5+
(func (import "foo:foo/bar" "foo") (param i32 i32 i32))
46
(memory (export "memory") 1)
57
(func (export "cabi_realloc") (param i32 i32 i32 i32) (result i32) unreachable)
68
)

0 commit comments

Comments
 (0)