Repository navigation
Open
Description
When a composition has several (implements "I") imports of the same interface, CompositionGraph::encode gives them all one instance type:
(import "primary" (implements "test:test/logger") (instance (;0;) (type 0)))
(import "backup" (implements "test:test/logger") (instance (;1;) (type 0)))Several labels for one interface is the case labelled imports exist for (#200). This happens:
- through implicit imports (an instantiated component's labelled imports left unsatisfied);
- through explicit
CompositionGraph::importnodes.
The output validates, and wasmtime runs it. But when the interface defines a type, wit-parser's decoder panics on it, and so does every tool built on that decoder:
wasm-tools component wit;- wit-bindgen;
- jco.
jco transpileaborts the same way (it uses wit-parser 0.259), so the composition can't be run in JavaScript.
The input component decodes fine: it's wit-component's shape, with one instance type per labelled import. Only wac's output has the shared type.
Reproduction
Cargo.toml:
[package]
name = "wac-implements-repro"
version = "0.1.0"
edition = "2024"
[dependencies]
wac-graph = "=0.12.0"
wit-parser = "=0.258.0"
wat = "1"src/main.rs:
use wac_graph::{types::Package, CompositionGraph, EncodeOptions};
/// A component importing one interface, which defines a type, under two
/// labels: the shape wit-component produces (one instance type per import).
const CONSUMER: &str = r#"
(component
(type (instance
(type (enum "debug" "info"))
(export "level" (type (eq 0)))
(type (func (param "level" 1) (param "message" string)))
(export "log" (func (type 2)))))
(import "primary" (implements "test:test/logger") (instance (type 0)))
(type (instance
(type (enum "debug" "info"))
(export "level" (type (eq 0)))
(type (func (param "level" 1) (param "message" string)))
(export "log" (func (type 2)))))
(import "backup" (implements "test:test/logger") (instance (type 1)))
)
"#;
fn main() {
let consumer = wat::parse_str(CONSUMER).unwrap();
// The input decodes fine.
wit_parser::decoding::decode(&consumer).expect("the consumer decodes");
println!("consumer: decodes");
let mut graph = CompositionGraph::new();
let package = Package::from_bytes("test:consumer", None, consumer, graph.types_mut()).unwrap();
let package = graph.register_package(package).unwrap();
graph.instantiate(package);
let composed = graph.encode(EncodeOptions::default()).unwrap();
println!("composed: {} bytes, validated by wac", composed.len());
// The composition does not: wit-parser panics.
wit_parser::decoding::decode(&composed).expect("the composition decodes");
println!("composition: decodes");
}Output:
consumer: decodes
composed: 348 bytes, validated by wac
thread 'main' panicked at wit-parser-0.258.0/src/decoding.rs:797:29:
assertion failed: prev.is_none()
Expected
The composition decodes as the input does: each labelled import has its own instance type, as wit-component encodes it.
Related
Metadata
Metadata
Assignees
Labels
No labels
Activity