Skip to content

Commit ff1db9e

Browse files
committed
Aggregate SemVer compatible interfaces
Signed-off-by: Brian Hardock <brian.hardock@fermyon.com>
1 parent 991ecf1 commit ff1db9e

File tree

18 files changed

+972
-15
lines changed

18 files changed

+972
-15
lines changed

crates/wac-graph/src/graph.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1553,7 +1553,8 @@ impl<'a> CompositionGraphEncoder<'a> {
15531553

15541554
// Populate the implicit argument map
15551555
for (name, node) in implicit_imports {
1556-
let (kind, index) = encoded[name];
1556+
let canonical = aggregator.canonical_import_name(name);
1557+
let (kind, index) = encoded[canonical];
15571558
state
15581559
.implicit_args
15591560
.entry(node)
@@ -1563,7 +1564,8 @@ impl<'a> CompositionGraphEncoder<'a> {
15631564

15641565
// Finally, populate the node indexes with the encoded explicit imports
15651566
for (name, node_index) in explicit_imports {
1566-
let (_, encoded_index) = encoded[name];
1567+
let canonical = aggregator.canonical_import_name(name);
1568+
let (_, encoded_index) = encoded[canonical];
15671569
state.node_indexes.insert(node_index, encoded_index);
15681570
}
15691571

crates/wac-graph/src/plug.rs

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
use crate::{types::SubtypeChecker, CompositionGraph, PackageId};
1+
use crate::{
2+
types::{are_semver_compatible, SubtypeChecker},
3+
CompositionGraph, PackageId,
4+
};
25
use thiserror::Error;
36

47
/// Represents an error that can occur when plugging components together.
@@ -28,31 +31,46 @@ pub fn plug(
2831
let socket_instantiation = graph.instantiate(socket);
2932

3033
for plug in plugs {
31-
let mut plug_exports = Vec::new();
34+
// Collect matching (plug_export_name, socket_import_name) pairs.
35+
// The names may differ when matched via semver compatibility.
36+
let mut plug_exports: Vec<(String, String)> = Vec::new();
3237
let mut cache = Default::default();
3338
let mut checker = SubtypeChecker::new(&mut cache);
3439
for (name, plug_ty) in &graph.types()[graph[plug].ty()].exports {
35-
if let Some(socket_ty) = graph.types()[graph[socket].ty()].imports.get(name) {
40+
// Try exact name match first, then fall back to semver-compatible match
41+
let matching_import = graph.types()[graph[socket].ty()]
42+
.imports
43+
.get(name)
44+
.map(|ty| (name.clone(), ty))
45+
.or_else(|| {
46+
graph.types()[graph[socket].ty()]
47+
.imports
48+
.iter()
49+
.find(|(import_name, _)| are_semver_compatible(name, import_name))
50+
.map(|(import_name, ty)| (import_name.clone(), ty))
51+
});
52+
53+
if let Some((socket_name, socket_ty)) = matching_import {
3654
if checker
3755
.is_subtype(*plug_ty, graph.types(), *socket_ty, graph.types())
3856
.is_ok()
3957
{
40-
plug_exports.push(name.clone());
58+
plug_exports.push((name.clone(), socket_name));
4159
}
4260
}
4361
}
4462

4563
// Instantiate the plug component
4664
let mut plug_instantiation = None;
47-
for plug_name in plug_exports {
65+
for (plug_name, socket_name) in plug_exports {
4866
log::debug!("using export `{plug_name}` for plug");
4967
let plug_instantiation =
5068
*plug_instantiation.get_or_insert_with(|| graph.instantiate(plug));
5169
let export = graph
5270
.alias_instance_export(plug_instantiation, &plug_name)
5371
.map_err(|err| PlugError::GraphError { source: err.into() })?;
5472
graph
55-
.set_instantiation_argument(socket_instantiation, &plug_name, export)
73+
.set_instantiation_argument(socket_instantiation, &socket_name, export)
5674
.map_err(|err| PlugError::GraphError { source: err.into() })?;
5775
}
5876
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
(component
2+
(type (;0;)
3+
(instance
4+
(export (;0;) "w" (type (sub resource)))
5+
(type (;1;) (record (field "x" u32)))
6+
(export (;2;) "x" (type (eq 1)))
7+
(type (;3;) (func (param "x" 2)))
8+
(export (;0;) "y" (func (type 3)))
9+
(export (;4;) "z" (type (sub resource)))
10+
)
11+
)
12+
(import "foo:bar/types@0.2.1" (instance (;0;) (type 0)))
13+
(type (;1;)
14+
(component
15+
(type (;0;)
16+
(instance
17+
(export (;0;) "w" (type (sub resource)))
18+
)
19+
)
20+
(import "foo:bar/types@0.2.1" (instance (;0;) (type 0)))
21+
)
22+
)
23+
(import "unlocked-dep=<test:higher>" (component (;0;) (type 1)))
24+
(instance (;1;) (instantiate 0
25+
(with "foo:bar/types@0.2.1" (instance 0))
26+
)
27+
)
28+
(type (;2;)
29+
(component
30+
(type (;0;)
31+
(instance
32+
(type (;0;) (record (field "x" u32)))
33+
(export (;1;) "x" (type (eq 0)))
34+
(type (;2;) (func (param "x" 1)))
35+
(export (;0;) "y" (func (type 2)))
36+
(export (;3;) "z" (type (sub resource)))
37+
)
38+
)
39+
(import "foo:bar/types@0.2.0" (instance (;0;) (type 0)))
40+
)
41+
)
42+
(import "unlocked-dep=<test:lower>" (component (;1;) (type 2)))
43+
(instance (;2;) (instantiate 1
44+
(with "foo:bar/types@0.2.0" (instance 0))
45+
)
46+
)
47+
)
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{
2+
"packages": [
3+
{
4+
"name": "test:higher",
5+
"path": "higher.wat"
6+
},
7+
{
8+
"name": "test:lower",
9+
"path": "lower.wat"
10+
}
11+
],
12+
"nodes": [
13+
{
14+
"type": "instantiation",
15+
"package": 0
16+
},
17+
{
18+
"type": "instantiation",
19+
"package": 1
20+
}
21+
]
22+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
(component
2+
(type
3+
(instance
4+
(export "w" (type (sub resource)))
5+
)
6+
)
7+
(import "foo:bar/types@0.2.1" (instance (type 0)))
8+
)
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
(component
2+
(type
3+
(instance
4+
(type (record (field "x" u32)))
5+
(export "x" (type (eq 0)))
6+
(type (func (param "x" 1)))
7+
(export "y" (func (type 2)))
8+
(export "z" (type (sub resource)))
9+
)
10+
)
11+
(import "foo:bar/types@0.2.0" (instance (type 0)))
12+
)
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
(component
2+
(type
3+
(instance
4+
(export "w" (type (sub resource)))
5+
)
6+
)
7+
(import "foo:bar/types@0.2.1" (instance (type 0)))
8+
)
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
(component
2+
(type (;0;)
3+
(instance
4+
(type (;0;) (record (field "x" u32)))
5+
(export (;1;) "x" (type (eq 0)))
6+
(type (;2;) (func (param "x" 1)))
7+
(export (;0;) "y" (func (type 2)))
8+
(export (;3;) "z" (type (sub resource)))
9+
(export (;4;) "w" (type (sub resource)))
10+
)
11+
)
12+
(import "foo:bar/types@0.2.1" (instance (;0;) (type 0)))
13+
(type (;1;)
14+
(component
15+
(type (;0;)
16+
(instance
17+
(type (;0;) (record (field "x" u32)))
18+
(export (;1;) "x" (type (eq 0)))
19+
(type (;2;) (func (param "x" 1)))
20+
(export (;0;) "y" (func (type 2)))
21+
(export (;3;) "z" (type (sub resource)))
22+
)
23+
)
24+
(import "foo:bar/types@0.2.0" (instance (;0;) (type 0)))
25+
)
26+
)
27+
(import "unlocked-dep=<test:foo>" (component (;0;) (type 1)))
28+
(instance (;1;) (instantiate 0
29+
(with "foo:bar/types@0.2.0" (instance 0))
30+
)
31+
)
32+
(type (;2;)
33+
(component
34+
(type (;0;)
35+
(instance
36+
(export (;0;) "w" (type (sub resource)))
37+
)
38+
)
39+
(import "foo:bar/types@0.2.1" (instance (;0;) (type 0)))
40+
)
41+
)
42+
(import "unlocked-dep=<test:bar>" (component (;1;) (type 2)))
43+
(instance (;2;) (instantiate 1
44+
(with "foo:bar/types@0.2.1" (instance 0))
45+
)
46+
)
47+
)
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
(component
2+
(type
3+
(instance
4+
(type (record (field "x" u32)))
5+
(export "x" (type (eq 0)))
6+
(type (func (param "x" 1)))
7+
(export "y" (func (type 2)))
8+
(export "z" (type (sub resource)))
9+
)
10+
)
11+
(import "foo:bar/types@0.2.0" (instance (type 0)))
12+
)
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{
2+
"packages": [
3+
{
4+
"name": "test:foo",
5+
"path": "foo.wat"
6+
},
7+
{
8+
"name": "test:bar",
9+
"path": "bar.wat"
10+
}
11+
],
12+
"nodes": [
13+
{
14+
"type": "instantiation",
15+
"package": 0
16+
},
17+
{
18+
"type": "instantiation",
19+
"package": 1
20+
}
21+
]
22+
}

0 commit comments

Comments
 (0)