Skip to content

Commit

Permalink
add first wit-component async test
Browse files Browse the repository at this point in the history
This required adding a new `wit_parser::decoding::decode_reader_with_features`
function for passing `WasmFeatures` to
`wasmparser::Validator::new_with_features`.

Signed-off-by: Joel Dice <[email protected]>
  • Loading branch information
dicej committed Nov 18, 2024
1 parent a9decd6 commit 5f91341
Show file tree
Hide file tree
Showing 8 changed files with 80 additions and 10 deletions.
1 change: 1 addition & 0 deletions crates/wit-component/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ serde_derive = { workspace = true }
serde_json = { workspace = true }

[dev-dependencies]
wasmparser = { workspace = true, features = ['component-model', 'features'] }
wasmprinter = { workspace = true, features = ['component-model'] }
glob = "0.3.0"
pretty_assertions = "1.3.0"
Expand Down
2 changes: 1 addition & 1 deletion crates/wit-component/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ pub use encoding::{encode, ComponentEncoder};
pub use linking::Linker;
pub use printing::*;
pub use targets::*;
pub use wit_parser::decoding::{decode, decode_reader, DecodedWasm};
pub use wit_parser::decoding::{decode, decode_reader, decode_reader_with_features, DecodedWasm};

pub mod metadata;

Expand Down
26 changes: 20 additions & 6 deletions crates/wit-component/tests/components.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use libtest_mimic::{Arguments, Trial};
use pretty_assertions::assert_eq;
use std::{borrow::Cow, fs, path::Path};
use wasm_encoder::{Encode, Section};
use wasmparser::{Parser, Validator, WasmFeatures};
use wit_component::{ComponentEncoder, DecodedWasm, Linker, StringEncoding, WitPrinter};
use wit_parser::{PackageId, Resolve, UnresolvedPackageGroup};

Expand Down Expand Up @@ -89,7 +90,7 @@ fn run_test(path: &Path) -> Result<()> {
.with_context(|| format!("failed to read core module at {module_path:?}"))?;
adapters
.try_fold(
ComponentEncoder::default().module(&module)?.validate(true),
ComponentEncoder::default().module(&module)?,
|encoder, path| {
let (name, wasm) = read_name_and_module("adapt-", &path?, &resolve, pkg_id)?;
Ok::<_, Error>(encoder.adapter(&name, &wasm)?)
Expand All @@ -108,7 +109,7 @@ fn run_test(path: &Path) -> Result<()> {
// Sort list to ensure deterministic order, which determines priority in cases of duplicate symbols:
libs.sort_by(|(_, a, _), (_, b, _)| a.cmp(b));

let mut linker = Linker::default().validate(true);
let mut linker = Linker::default().validate(false);

if path.join("stub-missing-functions").is_file() {
linker = linker.stub_missing_functions(true);
Expand Down Expand Up @@ -152,12 +153,25 @@ fn run_test(path: &Path) -> Result<()> {
}
};

let features =
WasmFeatures::WASM2 | WasmFeatures::COMPONENT_MODEL | WasmFeatures::COMPONENT_MODEL_ASYNC;
Validator::new_with_features(features)
.validate_all(&bytes)
.context("failed to validated component output")?;

let wat = wasmprinter::print_bytes(&bytes).context("failed to print bytes")?;
assert_output(&wat, &component_path)?;
let (pkg, resolve) = match wit_component::decode(&bytes).context("failed to decode resolve")? {
DecodedWasm::WitPackage(..) => unreachable!(),
DecodedWasm::Component(resolve, world) => (resolve.worlds[world].package.unwrap(), resolve),
};
let mut parser = Parser::new(0);
parser.set_features(features);
let (pkg, resolve) =
match wit_component::decode_reader_with_features(bytes.as_slice(), features)
.context("failed to decode resolve")?
{
DecodedWasm::WitPackage(..) => unreachable!(),
DecodedWasm::Component(resolve, world) => {
(resolve.worlds[world].package.unwrap(), resolve)
}
};
let wit = WitPrinter::default()
.print(&resolve, pkg, &[])
.context("failed to print WIT")?;
Expand Down
30 changes: 30 additions & 0 deletions crates/wit-component/tests/components/async-export/component.wat
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
(component
(core module (;0;)
(type (;0;) (func (param i32 i32) (result i32)))
(type (;1;) (func (param i32 i32 i32 i32) (result i32)))
(memory (;0;) 1)
(export "[async]foo" (func 0))
(export "memory" (memory 0))
(export "cabi_realloc" (func 1))
(func (;0;) (type 0) (param i32 i32) (result i32)
unreachable
)
(func (;1;) (type 1) (param i32 i32 i32 i32) (result i32)
unreachable
)
(@producers
(processed-by "wit-component" "$CARGO_PKG_VERSION")
(processed-by "my-fake-bindgen" "123.45")
)
)
(core instance (;0;) (instantiate 0))
(alias core export 0 "memory" (core memory (;0;)))
(type (;0;) (func (param "s" string) (result string)))
(alias core export 0 "[async]foo" (core func (;0;)))
(alias core export 0 "cabi_realloc" (core func (;1;)))
(func (;0;) (type 0) (canon lift (core func 0) (memory 0) (realloc 1) string-encoding=utf8 async))
(export (;1;) "foo" (func 0))
(@producers
(processed-by "wit-component" "$CARGO_PKG_VERSION")
)
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package root:component;

world root {
export foo: func(s: string) -> string;
}
5 changes: 5 additions & 0 deletions crates/wit-component/tests/components/async-export/module.wat
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
(module
(func (export "[async]foo") (param i32 i32) (result i32) unreachable)
(memory (export "memory") 1)
(func (export "cabi_realloc") (param i32 i32 i32 i32) (result i32) unreachable)
)
5 changes: 5 additions & 0 deletions crates/wit-component/tests/components/async-export/module.wit
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package foo:foo;

world module {
export foo: func(s: string) -> string;
}
16 changes: 13 additions & 3 deletions crates/wit-parser/src/decoding.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use wasmparser::{
types,
types::Types,
ComponentExternalKind, Parser, Payload, PrimitiveValType, ValidPayload, Validator,
WasmFeatures,
};

/// Represents information about a decoded WebAssembly component.
Expand Down Expand Up @@ -46,8 +47,8 @@ enum WitEncodingVersion {
impl ComponentInfo {
/// Creates a new component info by parsing the given WebAssembly component bytes.

fn from_reader(mut reader: impl Read) -> Result<Self> {
let mut validator = Validator::new();
fn from_reader(mut reader: impl Read, features: WasmFeatures) -> Result<Self> {
let mut validator = Validator::new_with_features(features);
let mut externs = Vec::new();
let mut depth = 1;
let mut types = None;
Expand Down Expand Up @@ -379,7 +380,16 @@ impl DecodedWasm {

/// Decode for incremental reading
pub fn decode_reader(reader: impl Read) -> Result<DecodedWasm> {
let info = ComponentInfo::from_reader(reader)?;
decode_reader_with_features(reader, WasmFeatures::default())
}

/// Like [`decode_reader`], but using caller-specified `WasmFeatures` when
/// validating input.
pub fn decode_reader_with_features(
reader: impl Read,
features: WasmFeatures,
) -> Result<DecodedWasm> {
let info = ComponentInfo::from_reader(reader, features)?;

if let Some(version) = info.is_wit_package() {
match version {
Expand Down

0 comments on commit 5f91341

Please sign in to comment.