Skip to content

Commit f398c13

Browse files
authored
Merge pull request #67 from peterhuene/fix-aggregation
Fix aggregation of imports.
2 parents 2d25c05 + 6072bc3 commit f398c13

8 files changed

Lines changed: 545 additions & 122 deletions

File tree

Cargo.lock

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/wac-graph/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ wasmprinter = { workspace = true }
2828
wat = { workspace = true }
2929
serde = { workspace = true }
3030
serde_json = { workspace = true }
31+
wit-component = { workspace = true, features = ["dummy-module"] }
32+
wit-parser = { workspace = true }
3133

3234
[features]
3335
serde = ["dep:serde", "wac-types/serde"]

crates/wac-graph/src/graph.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1351,6 +1351,7 @@ impl<'a> CompositionGraphEncoder<'a> {
13511351
let mut arguments = Vec::new();
13521352
let mut encoded = HashMap::new();
13531353
let mut cache = Default::default();
1354+
let mut checker = SubtypeChecker::new(&mut cache);
13541355

13551356
// Enumerate the instantiation nodes and populate the import types
13561357
for node in self.0.nodes() {
@@ -1379,7 +1380,7 @@ impl<'a> CompositionGraphEncoder<'a> {
13791380
}
13801381

13811382
aggregator = aggregator
1382-
.aggregate(name, package.types(), *kind, &mut cache)
1383+
.aggregate(name, package.types(), *kind, &mut checker)
13831384
.map_err(|e| Error::ImportTypeMergeConflict {
13841385
import: name.clone(),
13851386
source: e,
@@ -1404,6 +1405,11 @@ impl<'a> CompositionGraphEncoder<'a> {
14041405
},
14051406
);
14061407

1408+
// Ensure we insert an instance index into the current scope
1409+
if let ItemKind::Instance(id) = kind {
1410+
state.current.instances.insert(id, index);
1411+
}
1412+
14071413
let prev = encoded.insert(name, (kind.into(), index));
14081414
assert!(prev.is_none());
14091415
}

crates/wac-graph/tests/encoding.rs

Lines changed: 52 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,13 @@ use semver::Version;
44
use serde::Deserialize;
55
use std::{
66
collections::HashMap,
7+
ffi::OsStr,
78
fs::{self, File},
89
path::{Path, PathBuf},
910
};
1011
use wac_graph::{types::Package, CompositionGraph, EncodeOptions, NodeId, PackageId};
12+
use wit_component::{ComponentEncoder, StringEncoding};
13+
use wit_parser::Resolve;
1114

1215
/// Represents a node to add to a composition graph.
1316
#[derive(Deserialize)]
@@ -118,12 +121,52 @@ impl GraphFile {
118121

119122
for (index, package) in self.packages.iter().enumerate() {
120123
let path = root.join(&package.path);
121-
let bytes = wat::parse_file(&path).with_context(|| {
122-
format!(
123-
"failed to parse package `{path}` for test case `{test_case}`",
124-
path = path.display()
125-
)
126-
})?;
124+
let bytes = match path.extension().and_then(OsStr::to_str) {
125+
Some("wit") => {
126+
let mut resolve = Resolve::default();
127+
let id = resolve.push_file(&path).with_context(|| {
128+
format!(
129+
"failed to parse package file `{path}` for test case `{test_case}`",
130+
path = path.display()
131+
)
132+
})?;
133+
let world = resolve.select_world(id, None).with_context(|| {
134+
format!(
135+
"failed to select world from `{path}` for test case `{test_case}`",
136+
path = path.display()
137+
)
138+
})?;
139+
140+
let mut module = wit_component::dummy_module(&resolve, world);
141+
wit_component::embed_component_metadata(
142+
&mut module,
143+
&resolve,
144+
world,
145+
StringEncoding::default(),
146+
)
147+
.with_context(|| {
148+
format!(
149+
"failed to embed component metadata from package `{path}` for test case `{test_case}`",
150+
path = path.display()
151+
)
152+
})?;
153+
154+
let encoder = ComponentEncoder::default().validate(true).module(&module)?;
155+
encoder
156+
.encode()
157+
.with_context(|| format!("failed to encode a component from module derived from package `{path}` for test case `{test_case}`", path = path.display()))?
158+
}
159+
Some("wat") => wat::parse_file(&path).with_context(|| {
160+
format!(
161+
"failed to parse package `{path}` for test case `{test_case}`",
162+
path = path.display()
163+
)
164+
})?,
165+
_ => bail!(
166+
"unexpected file extension for package file `{path}`",
167+
path = package.path.display()
168+
),
169+
};
127170

128171
let package = Package::from_bytes(&package.name, package.version.as_ref(), bytes)
129172
.with_context(|| {
@@ -226,6 +269,9 @@ impl GraphFile {
226269
/// * [required] `graph.json` - a JSON representation of a composition graph
227270
/// (see above for serialization format).
228271
/// * [optional] `*.wat` - packages (i.e. components) referenced from `graph.json`.
272+
/// * [optional] `*.wit` - packages (i.e. components) referenced from `graph.json`;
273+
/// the file is expected to contain a single world representing the world of
274+
/// the component; a dummy module will be created to implement the component.
229275
///
230276
/// And the output files are one of the following:
231277
///
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package foo:bar;
2+
3+
interface baz {
4+
resource x;
5+
}
6+
7+
interface qux {
8+
use baz.{x};
9+
f: func() -> x;
10+
}
11+
12+
world w {
13+
import qux;
14+
export qux;
15+
}
Lines changed: 198 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,198 @@
1+
(component
2+
(type (;0;)
3+
(instance
4+
(export (;0;) "x" (type (sub resource)))
5+
)
6+
)
7+
(import "foo:bar/baz" (instance (;0;) (type 0)))
8+
(alias export 0 "x" (type (;1;)))
9+
(type (;2;)
10+
(instance
11+
(alias outer 1 1 (type (;0;)))
12+
(export (;1;) "x" (type (eq 0)))
13+
(type (;2;) (own 1))
14+
(type (;3;) (func (result 2)))
15+
(export (;0;) "f" (func (type 3)))
16+
)
17+
)
18+
(import "foo:bar/qux" (instance (;1;) (type 2)))
19+
(component (;0;)
20+
(type (;0;)
21+
(instance
22+
(export (;0;) "x" (type (sub resource)))
23+
)
24+
)
25+
(import "foo:bar/baz" (instance (;0;) (type 0)))
26+
(alias export 0 "x" (type (;1;)))
27+
(type (;2;)
28+
(instance
29+
(alias outer 1 1 (type (;0;)))
30+
(export (;1;) "x" (type (eq 0)))
31+
(type (;2;) (own 1))
32+
(type (;3;) (func (result 2)))
33+
(export (;0;) "f" (func (type 3)))
34+
)
35+
)
36+
(import "foo:bar/qux" (instance (;1;) (type 2)))
37+
(core module (;0;)
38+
(type (;0;) (func (param i32)))
39+
(type (;1;) (func (result i32)))
40+
(type (;2;) (func (param i32 i32 i32 i32) (result i32)))
41+
(import "foo:bar/baz" "[resource-drop]x" (func (;0;) (type 0)))
42+
(import "foo:bar/qux" "f" (func (;1;) (type 1)))
43+
(func (;2;) (type 1) (result i32)
44+
unreachable
45+
)
46+
(func (;3;) (type 2) (param i32 i32 i32 i32) (result i32)
47+
unreachable
48+
)
49+
(memory (;0;) 0)
50+
(export "foo:bar/qux#f" (func 2))
51+
(export "memory" (memory 0))
52+
(export "cabi_realloc" (func 3))
53+
(@producers
54+
(processed-by "wit-component" "0.202.0")
55+
)
56+
)
57+
(alias export 0 "x" (type (;3;)))
58+
(core func (;0;) (canon resource.drop 3))
59+
(core instance (;0;)
60+
(export "[resource-drop]x" (func 0))
61+
)
62+
(alias export 1 "f" (func (;0;)))
63+
(core func (;1;) (canon lower (func 0)))
64+
(core instance (;1;)
65+
(export "f" (func 1))
66+
)
67+
(core instance (;2;) (instantiate 0
68+
(with "foo:bar/baz" (instance 0))
69+
(with "foo:bar/qux" (instance 1))
70+
)
71+
)
72+
(alias core export 2 "memory" (core memory (;0;)))
73+
(alias core export 2 "cabi_realloc" (core func (;2;)))
74+
(alias export 0 "x" (type (;4;)))
75+
(type (;5;) (own 4))
76+
(type (;6;) (func (result 5)))
77+
(alias core export 2 "foo:bar/qux#f" (core func (;3;)))
78+
(func (;1;) (type 6) (canon lift (core func 3)))
79+
(alias export 0 "x" (type (;7;)))
80+
(component (;0;)
81+
(import "import-type-x" (type (;0;) (sub resource)))
82+
(import "import-type-x0" (type (;1;) (eq 0)))
83+
(type (;2;) (own 1))
84+
(type (;3;) (func (result 2)))
85+
(import "import-func-f" (func (;0;) (type 3)))
86+
(export (;4;) "x" (type 0))
87+
(type (;5;) (own 4))
88+
(type (;6;) (func (result 5)))
89+
(export (;1;) "f" (func 0) (func (type 6)))
90+
)
91+
(instance (;2;) (instantiate 0
92+
(with "import-func-f" (func 1))
93+
(with "import-type-x" (type 7))
94+
(with "import-type-x0" (type 4))
95+
)
96+
)
97+
(export (;3;) "foo:bar/qux" (instance 2))
98+
(@producers
99+
(processed-by "wit-component" "0.202.0")
100+
)
101+
)
102+
(instance $component2 (;2;) (instantiate 0
103+
(with "foo:bar/baz" (instance 0))
104+
(with "foo:bar/qux" (instance 1))
105+
)
106+
)
107+
(alias export $component2 "foo:bar/qux" (instance $alias (;3;)))
108+
(component (;1;)
109+
(type (;0;)
110+
(instance
111+
(export (;0;) "x" (type (sub resource)))
112+
)
113+
)
114+
(import "foo:bar/baz" (instance (;0;) (type 0)))
115+
(alias export 0 "x" (type (;1;)))
116+
(type (;2;)
117+
(instance
118+
(alias outer 1 1 (type (;0;)))
119+
(export (;1;) "x" (type (eq 0)))
120+
(type (;2;) (own 1))
121+
(type (;3;) (func (result 2)))
122+
(export (;0;) "f" (func (type 3)))
123+
)
124+
)
125+
(import "foo:bar/qux" (instance (;1;) (type 2)))
126+
(core module (;0;)
127+
(type (;0;) (func (param i32)))
128+
(type (;1;) (func (result i32)))
129+
(type (;2;) (func (param i32 i32 i32 i32) (result i32)))
130+
(import "foo:bar/baz" "[resource-drop]x" (func (;0;) (type 0)))
131+
(import "foo:bar/qux" "f" (func (;1;) (type 1)))
132+
(func (;2;) (type 1) (result i32)
133+
unreachable
134+
)
135+
(func (;3;) (type 2) (param i32 i32 i32 i32) (result i32)
136+
unreachable
137+
)
138+
(memory (;0;) 0)
139+
(export "foo:bar/qux#f" (func 2))
140+
(export "memory" (memory 0))
141+
(export "cabi_realloc" (func 3))
142+
(@producers
143+
(processed-by "wit-component" "0.202.0")
144+
)
145+
)
146+
(alias export 0 "x" (type (;3;)))
147+
(core func (;0;) (canon resource.drop 3))
148+
(core instance (;0;)
149+
(export "[resource-drop]x" (func 0))
150+
)
151+
(alias export 1 "f" (func (;0;)))
152+
(core func (;1;) (canon lower (func 0)))
153+
(core instance (;1;)
154+
(export "f" (func 1))
155+
)
156+
(core instance (;2;) (instantiate 0
157+
(with "foo:bar/baz" (instance 0))
158+
(with "foo:bar/qux" (instance 1))
159+
)
160+
)
161+
(alias core export 2 "memory" (core memory (;0;)))
162+
(alias core export 2 "cabi_realloc" (core func (;2;)))
163+
(alias export 0 "x" (type (;4;)))
164+
(type (;5;) (own 4))
165+
(type (;6;) (func (result 5)))
166+
(alias core export 2 "foo:bar/qux#f" (core func (;3;)))
167+
(func (;1;) (type 6) (canon lift (core func 3)))
168+
(alias export 0 "x" (type (;7;)))
169+
(component (;0;)
170+
(import "import-type-x" (type (;0;) (sub resource)))
171+
(import "import-type-x0" (type (;1;) (eq 0)))
172+
(type (;2;) (own 1))
173+
(type (;3;) (func (result 2)))
174+
(import "import-func-f" (func (;0;) (type 3)))
175+
(export (;4;) "x" (type 0))
176+
(type (;5;) (own 4))
177+
(type (;6;) (func (result 5)))
178+
(export (;1;) "f" (func 0) (func (type 6)))
179+
)
180+
(instance (;2;) (instantiate 0
181+
(with "import-func-f" (func 1))
182+
(with "import-type-x" (type 7))
183+
(with "import-type-x0" (type 4))
184+
)
185+
)
186+
(export (;3;) "foo:bar/qux" (instance 2))
187+
(@producers
188+
(processed-by "wit-component" "0.202.0")
189+
)
190+
)
191+
(instance $component1 (;4;) (instantiate 1
192+
(with "foo:bar/qux" (instance $alias))
193+
(with "foo:bar/baz" (instance 0))
194+
)
195+
)
196+
(alias export $component1 "foo:bar/qux" (instance $export (;5;)))
197+
(export (;6;) "foo:bar/qux" (instance $export))
198+
)

0 commit comments

Comments
 (0)