Repository: bytecodealliance/wasm-tools
Pull request #2070 (2025-02-24 21:24:07)

Update validation of `{future,stream}.close-readable`
Account for changes in WebAssembly/component-model#446 and update the validation here to expect two `i32` parameters instead of only one.


Patch:
diff --git a/crates/wasmparser/src/validator/component.rs b/crates/wasmparser/src/validator/component.rs
index 62b855c0..161541f3 100644
--- a/crates/wasmparser/src/validator/component.rs
+++ b/crates/wasmparser/src/validator/component.rs
@@ -1437,7 +1437,7 @@ impl ComponentState {
         };
 
         self.core_funcs
-            .push(types.intern_func_type(FuncType::new([ValType::I32], []), offset));
+            .push(types.intern_func_type(FuncType::new([ValType::I32; 2], []), offset));
         Ok(())
     }
 
@@ -1621,7 +1621,7 @@ impl ComponentState {
         };
 
         self.core_funcs
-            .push(types.intern_func_type(FuncType::new([ValType::I32], []), offset));
+            .push(types.intern_func_type(FuncType::new([ValType::I32; 2], []), offset));
         Ok(())
     }
 
diff --git a/crates/wit-component/src/validation.rs b/crates/wit-component/src/validation.rs
index aeb62614..c78ff8c5 100644
--- a/crates/wit-component/src/validation.rs
+++ b/crates/wit-component/src/validation.rs
@@ -888,7 +888,7 @@ impl ImportMap {
             if async_ {
                 bail!("async `future.close-readable` calls not supported");
             }
-            validate_func_sig(name, &FuncType::new([ValType::I32], []), ty)?;
+            validate_func_sig(name, &FuncType::new([ValType::I32; 2], []), ty)?;
             Import::FutureCloseReadable(info)
         } else if let Some(info) = prefixed_payload("[stream-new-") {
             if async_ {
@@ -918,7 +918,7 @@ impl ImportMap {
             if async_ {
                 bail!("async `stream.close-readable` calls not supported");
             }
-            validate_func_sig(name, &FuncType::new([ValType::I32], []), ty)?;
+            validate_func_sig(name, &FuncType::new([ValType::I32; 2], []), ty)?;
             Import::StreamCloseReadable(info)
         } else {
             return Ok(None);
diff --git a/crates/wit-parser/src/resolve.rs b/crates/wit-parser/src/resolve.rs
index 764d64a7..2f8de7c1 100644
--- a/crates/wit-parser/src/resolve.rs
+++ b/crates/wit-parser/src/resolve.rs
@@ -2644,7 +2644,13 @@ impl Remap {
             worlds: Default::default(),
         });
         let prev = resolve.package_names.insert(unresolved.name.clone(), pkgid);
-        assert!(prev.is_none());
+        if let Some(prev) = prev {
+            resolve.package_names.insert(unresolved.name.clone(), prev);
+            bail!(
+                "attempting to re-add package `{}` when it's already present in this `Resolve`",
+                unresolved.name,
+            );
+        }
 
         self.process_foreign_deps(resolve, pkgid, &unresolved)?;
 
diff --git a/src/bin/wasm-tools/metadata.rs b/src/bin/wasm-tools/metadata.rs
index cfa83536..364b902d 100644
--- a/src/bin/wasm-tools/metadata.rs
+++ b/src/bin/wasm-tools/metadata.rs
@@ -54,7 +54,7 @@ impl ShowOpts {
         if self.json {
             write!(output, "{}", serde_json::to_string(&payload)?)?;
         } else {
-            fmt_payload(&payload, &mut output)?;
+            write_table(&payload, &mut output)?;
         }
         Ok(())
     }
@@ -89,7 +89,9 @@ impl AddOpts {
     }
 }
 
-fn fmt_payload(payload: &Payload, f: &mut Box<dyn WriteColor>) -> Result<()> {
+/// Write a table containing a wasm binary's metadata to a writer
+fn write_table(payload: &Payload, f: &mut Box<dyn WriteColor>) -> Result<()> {
+    // Prepare a table and get the individual metadata
     let mut table = Table::new();
     table
         .load_preset(UTF8_FULL)
@@ -110,43 +112,60 @@ fn fmt_payload(payload: &Payload, f: &mut Box<dyn WriteColor>) -> Result<()> {
         version,
     } = payload.metadata();
 
-    // Print the basic information
+    // Add the basic information to the table first
     let kind = match payload {
         Payload::Component { .. } => "component",
         Payload::Module(_) => "module",
     };
     table.add_row(vec!["kind", &kind]);
-    let name = name.as_deref().unwrap_or("<unknown>");
-    table.add_row(vec!["name", &name]);
     table.add_row(vec![
         "range",
         &format!("0x{:x}..0x{:x}", range.start, range.end),
     ]);
+    let name = name.as_deref().unwrap_or("<unknown>");
+    table.add_row(vec!["name", &name]);
 
-    // Print the OCI annotations
+    // Add the OCI annotations to the table
     if let Some(description) = description {
         table.add_row(vec!["description", &description.to_string()]);
     }
-    if let Some(licenses) = licenses {
-        table.add_row(vec!["licenses", &licenses.to_string()]);
-    }
     if let Some(authors) = authors {
         table.add_row(vec!["authors", &authors.to_string()]);
     }
+    if let Some(version) = version {
+        table.add_row(vec!["version", &version.to_string()]);
+    }
+    if let Some(revision) = revision {
+        table.add_row(vec!["revision", &revision.to_string()]);
+    }
+    if let Some(licenses) = licenses {
+        table.add_row(vec!["licenses", &licenses.to_string()]);
+    }
     if let Some(source) = source {
         table.add_row(vec!["source", &source.to_string()]);
     }
     if let Some(homepage) = homepage {
         table.add_row(vec!["homepage", &homepage.to_string()]);
     }
-    if let Some(revision) = revision {
-        table.add_row(vec!["revision", &revision.to_string()]);
-    }
-    if let Some(version) = version {
-        table.add_row(vec!["version", &version.to_string()]);
-    }
 
+    // Add the producer section to the table
     if let Some(producers) = producers {
+        // Ensure the "language" fields are listed first
+        let mut producers = producers
+            .iter()
+            .map(|(n, p)| (n.clone(), p))
+            .collect::<Vec<_>>();
+        producers.sort_by(|(a, _), (b, _)| {
+            if a == "language" {
+                std::cmp::Ordering::Less
+            } else if b == "language" {
+                std::cmp::Ordering::Greater
+            } else {
+                a.cmp(b)
+            }
+        });
+
+        // Add the producers to the table
         for (name, pairs) in producers.iter() {
             for (field, version) in pairs.iter() {
                 match version.len() {
@@ -160,9 +179,10 @@ fn fmt_payload(payload: &Payload, f: &mut Box<dyn WriteColor>) -> Result<()> {
     // Write the table to the writer
     writeln!(f, "{table}")?;
 
+    // Recursively print any children
     if let Payload::Component { children, .. } = payload {
         for payload in children {
-            fmt_payload(payload, f)?;
+            write_table(payload, f)?;
         }
     }
 


Test patch:
diff --git a/crates/wit-component/tests/components/async-streams-and-futures/component.wat b/crates/wit-component/tests/components/async-streams-and-futures/component.wat
index 4e0883c6..0f3af2f0 100644
--- a/crates/wit-component/tests/components/async-streams-and-futures/component.wat
+++ b/crates/wit-component/tests/components/async-streams-and-futures/component.wat
@@ -19,9 +19,8 @@
     (type (;1;) (func (result i32)))
     (type (;2;) (func (param i32 i32 i32) (result i32)))
     (type (;3;) (func (param i32) (result i32)))
-    (type (;4;) (func (param i32)))
-    (type (;5;) (func (param i32 i32)))
-    (type (;6;) (func (param i32 i32 i32 i32) (result i32)))
+    (type (;4;) (func (param i32 i32)))
+    (type (;5;) (func (param i32 i32 i32 i32) (result i32)))
     (import "$root" "[async]foo" (func (;0;) (type 0)))
     (import "foo:foo/bar" "[async]foo" (func (;1;) (type 0)))
     (import "$root" "[stream-new-2]foo" (func (;2;) (type 1)))
@@ -30,96 +29,96 @@
     (import "$root" "[stream-cancel-read-2]foo" (func (;5;) (type 3)))
     (import "$root" "[stream-cancel-write-2]foo" (func (;6;) (type 3)))
     (import "$root" "[stream-close-readable-2]foo" (func (;7;) (type 4)))
-    (import "$root" "[stream-close-writable-2]foo" (func (;8;) (type 5)))
+    (import "$root" "[stream-close-writable-2]foo" (func (;8;) (type 4)))
     (import "foo:foo/bar" "[stream-new-2]foo" (func (;9;) (type 1)))
     (import "foo:foo/bar" "[stream-read-2]foo" (func (;10;) (type 2)))
     (import "foo:foo/bar" "[stream-write-2]foo" (func (;11;) (type 2)))
     (import "foo:foo/bar" "[stream-cancel-read-2]foo" (func (;12;) (type 3)))
     (import "foo:foo/bar" "[stream-cancel-write-2]foo" (func (;13;) (type 3)))
     (import "foo:foo/bar" "[stream-close-readable-2]foo" (func (;14;) (type 4)))
-    (import "foo:foo/bar" "[stream-close-writable-2]foo" (func (;15;) (type 5)))
+    (import "foo:foo/bar" "[stream-close-writable-2]foo" (func (;15;) (type 4)))
     (import "$root" "[future-new-0]foo" (func (;16;) (type 1)))
     (import "$root" "[future-read-0]foo" (func (;17;) (type 0)))
     (import "$root" "[future-write-0]foo" (func (;18;) (type 0)))
     (import "$root" "[future-cancel-read-0]foo" (func (;19;) (type 3)))
     (import "$root" "[future-cancel-write-0]foo" (func (;20;) (type 3)))
     (import "$root" "[future-close-readable-0]foo" (func (;21;) (type 4)))
-    (import "$root" "[future-close-writable-0]foo" (func (;22;) (type 5)))
+    (import "$root" "[future-close-writable-0]foo" (func (;22;) (type 4)))
     (import "foo:foo/bar" "[future-new-0]foo" (func (;23;) (type 1)))
     (import "foo:foo/bar" "[future-read-0]foo" (func (;24;) (type 0)))
     (import "foo:foo/bar" "[future-write-0]foo" (func (;25;) (type 0)))
     (import "foo:foo/bar" "[future-cancel-read-0]foo" (func (;26;) (type 3)))
     (import "foo:foo/bar" "[future-cancel-write-0]foo" (func (;27;) (type 3)))
     (import "foo:foo/bar" "[future-close-readable-0]foo" (func (;28;) (type 4)))
-    (import "foo:foo/bar" "[future-close-writable-0]foo" (func (;29;) (type 5)))
+    (import "foo:foo/bar" "[future-close-writable-0]foo" (func (;29;) (type 4)))
     (import "$root" "[future-new-1]foo" (func (;30;) (type 1)))
     (import "$root" "[future-read-1]foo" (func (;31;) (type 0)))
     (import "$root" "[future-write-1]foo" (func (;32;) (type 0)))
     (import "$root" "[future-cancel-read-1]foo" (func (;33;) (type 3)))
     (import "$root" "[future-cancel-write-1]foo" (func (;34;) (type 3)))
     (import "$root" "[future-close-readable-1]foo" (func (;35;) (type 4)))
-    (import "$root" "[future-close-writable-1]foo" (func (;36;) (type 5)))
+    (import "$root" "[future-close-writable-1]foo" (func (;36;) (type 4)))
     (import "foo:foo/bar" "[future-new-1]foo" (func (;37;) (type 1)))
     (import "foo:foo/bar" "[future-read-1]foo" (func (;38;) (type 0)))
     (import "foo:foo/bar" "[future-write-1]foo" (func (;39;) (type 0)))
     (import "foo:foo/bar" "[future-cancel-read-1]foo" (func (;40;) (type 3)))
     (import "foo:foo/bar" "[future-cancel-write-1]foo" (func (;41;) (type 3)))
     (import "foo:foo/bar" "[future-close-readable-1]foo" (func (;42;) (type 4)))
-    (import "foo:foo/bar" "[future-close-writable-1]foo" (func (;43;) (type 5)))
+    (import "foo:foo/bar" "[future-close-writable-1]foo" (func (;43;) (type 4)))
     (import "[export]$root" "[stream-new-2]foo" (func (;44;) (type 1)))
     (import "[export]$root" "[stream-read-2]foo" (func (;45;) (type 2)))
     (import "[export]$root" "[stream-write-2]foo" (func (;46;) (type 2)))
     (import "[export]$root" "[stream-cancel-read-2]foo" (func (;47;) (type 3)))
     (import "[export]$root" "[stream-cancel-write-2]foo" (func (;48;) (type 3)))
     (import "[export]$root" "[stream-close-readable-2]foo" (func (;49;) (type 4)))
-    (import "[export]$root" "[stream-close-writable-2]foo" (func (;50;) (type 5)))
+    (import "[export]$root" "[stream-close-writable-2]foo" (func (;50;) (type 4)))
     (import "[export]foo:foo/bar" "[stream-new-2]foo" (func (;51;) (type 1)))
     (import "[export]foo:foo/bar" "[stream-read-2]foo" (func (;52;) (type 2)))
     (import "[export]foo:foo/bar" "[stream-write-2]foo" (func (;53;) (type 2)))
     (import "[export]foo:foo/bar" "[stream-cancel-read-2]foo" (func (;54;) (type 3)))
     (import "[export]foo:foo/bar" "[stream-cancel-write-2]foo" (func (;55;) (type 3)))
     (import "[export]foo:foo/bar" "[stream-close-readable-2]foo" (func (;56;) (type 4)))
-    (import "[export]foo:foo/bar" "[stream-close-writable-2]foo" (func (;57;) (type 5)))
+    (import "[export]foo:foo/bar" "[stream-close-writable-2]foo" (func (;57;) (type 4)))
     (import "[export]$root" "[future-new-0]foo" (func (;58;) (type 1)))
     (import "[export]$root" "[future-read-0]foo" (func (;59;) (type 0)))
     (import "[export]$root" "[future-write-0]foo" (func (;60;) (type 0)))
     (import "[export]$root" "[future-cancel-read-0]foo" (func (;61;) (type 3)))
     (import "[export]$root" "[future-cancel-write-0]foo" (func (;62;) (type 3)))
     (import "[export]$root" "[future-close-readable-0]foo" (func (;63;) (type 4)))
-    (import "[export]$root" "[future-close-writable-0]foo" (func (;64;) (type 5)))
+    (import "[export]$root" "[future-close-writable-0]foo" (func (;64;) (type 4)))
     (import "[export]foo:foo/bar" "[future-new-0]foo" (func (;65;) (type 1)))
     (import "[export]foo:foo/bar" "[future-read-0]foo" (func (;66;) (type 0)))
     (import "[export]foo:foo/bar" "[future-write-0]foo" (func (;67;) (type 0)))
     (import "[export]foo:foo/bar" "[future-cancel-read-0]foo" (func (;68;) (type 3)))
     (import "[export]foo:foo/bar" "[future-cancel-write-0]foo" (func (;69;) (type 3)))
     (import "[export]foo:foo/bar" "[future-close-readable-0]foo" (func (;70;) (type 4)))
-    (import "[export]foo:foo/bar" "[future-close-writable-0]foo" (func (;71;) (type 5)))
+    (import "[export]foo:foo/bar" "[future-close-writable-0]foo" (func (;71;) (type 4)))
     (import "[export]$root" "[future-new-1]foo" (func (;72;) (type 1)))
     (import "[export]$root" "[future-read-1]foo" (func (;73;) (type 0)))
     (import "[export]$root" "[future-write-1]foo" (func (;74;) (type 0)))
     (import "[export]$root" "[future-cancel-read-1]foo" (func (;75;) (type 3)))
     (import "[export]$root" "[future-cancel-write-1]foo" (func (;76;) (type 3)))
     (import "[export]$root" "[future-close-readable-1]foo" (func (;77;) (type 4)))
-    (import "[export]$root" "[future-close-writable-1]foo" (func (;78;) (type 5)))
+    (import "[export]$root" "[future-close-writable-1]foo" (func (;78;) (type 4)))
     (import "[export]foo:foo/bar" "[future-new-1]foo" (func (;79;) (type 1)))
     (import "[export]foo:foo/bar" "[future-read-1]foo" (func (;80;) (type 0)))
     (import "[export]foo:foo/bar" "[future-write-1]foo" (func (;81;) (type 0)))
     (import "[export]foo:foo/bar" "[future-cancel-read-1]foo" (func (;82;) (type 3)))
     (import "[export]foo:foo/bar" "[future-cancel-write-1]foo" (func (;83;) (type 3)))
     (import "[export]foo:foo/bar" "[future-close-readable-1]foo" (func (;84;) (type 4)))
-    (import "[export]foo:foo/bar" "[future-close-writable-1]foo" (func (;85;) (type 5)))
+    (import "[export]foo:foo/bar" "[future-close-writable-1]foo" (func (;85;) (type 4)))
     (memory (;0;) 1)
     (export "[async-stackful]foo" (func 86))
     (export "[async-stackful]foo:foo/bar#foo" (func 87))
     (export "memory" (memory 0))
     (export "cabi_realloc" (func 88))
-    (func (;86;) (type 5) (param i32 i32)
+    (func (;86;) (type 4) (param i32 i32)
       unreachable
     )
-    (func (;87;) (type 5) (param i32 i32)
+    (func (;87;) (type 4) (param i32 i32)
       unreachable
     )
-    (func (;88;) (type 6) (param i32 i32 i32 i32) (result i32)
+    (func (;88;) (type 5) (param i32 i32 i32 i32) (result i32)
       unreachable
     )
     (@producers
diff --git a/crates/wit-component/tests/components/async-streams-and-futures/module.wat b/crates/wit-component/tests/components/async-streams-and-futures/module.wat
index 934fa4bb..952d7699 100644
--- a/crates/wit-component/tests/components/async-streams-and-futures/module.wat
+++ b/crates/wit-component/tests/components/async-streams-and-futures/module.wat
@@ -6,84 +6,84 @@
   (func (import "$root" "[stream-write-2]foo") (param i32 i32 i32) (result i32))
   (func (import "$root" "[stream-cancel-read-2]foo") (param i32) (result i32))
   (func (import "$root" "[stream-cancel-write-2]foo") (param i32) (result i32))
-  (func (import "$root" "[stream-close-readable-2]foo") (param i32))
+  (func (import "$root" "[stream-close-readable-2]foo") (param i32 i32))
   (func (import "$root" "[stream-close-writable-2]foo") (param i32 i32))
   (func (import "foo:foo/bar" "[stream-new-2]foo") (result i32))
   (func (import "foo:foo/bar" "[stream-read-2]foo") (param i32 i32 i32) (result i32))
   (func (import "foo:foo/bar" "[stream-write-2]foo") (param i32 i32 i32) (result i32))
   (func (import "foo:foo/bar" "[stream-cancel-read-2]foo") (param i32) (result i32))
   (func (import "foo:foo/bar" "[stream-cancel-write-2]foo") (param i32) (result i32))
-  (func (import "foo:foo/bar" "[stream-close-readable-2]foo") (param i32))
+  (func (import "foo:foo/bar" "[stream-close-readable-2]foo") (param i32 i32))
   (func (import "foo:foo/bar" "[stream-close-writable-2]foo") (param i32 i32))
   (func (import "$root" "[future-new-0]foo") (result i32))
   (func (import "$root" "[future-read-0]foo") (param i32 i32) (result i32))
   (func (import "$root" "[future-write-0]foo") (param i32 i32) (result i32))
   (func (import "$root" "[future-cancel-read-0]foo") (param i32) (result i32))
   (func (import "$root" "[future-cancel-write-0]foo") (param i32) (result i32))
-  (func (import "$root" "[future-close-readable-0]foo") (param i32))
+  (func (import "$root" "[future-close-readable-0]foo") (param i32 i32))
   (func (import "$root" "[future-close-writable-0]foo") (param i32 i32))
   (func (import "foo:foo/bar" "[future-new-0]foo") (result i32))
   (func (import "foo:foo/bar" "[future-read-0]foo") (param i32 i32) (result i32))
   (func (import "foo:foo/bar" "[future-write-0]foo") (param i32 i32) (result i32))
   (func (import "foo:foo/bar" "[future-cancel-read-0]foo") (param i32) (result i32))
   (func (import "foo:foo/bar" "[future-cancel-write-0]foo") (param i32) (result i32))
-  (func (import "foo:foo/bar" "[future-close-readable-0]foo") (param i32))
+  (func (import "foo:foo/bar" "[future-close-readable-0]foo") (param i32 i32))
   (func (import "foo:foo/bar" "[future-close-writable-0]foo") (param i32 i32))
   (func (import "$root" "[future-new-1]foo") (result i32))
   (func (import "$root" "[future-read-1]foo") (param i32 i32) (result i32))
   (func (import "$root" "[future-write-1]foo") (param i32 i32) (result i32))
   (func (import "$root" "[future-cancel-read-1]foo") (param i32) (result i32))
   (func (import "$root" "[future-cancel-write-1]foo") (param i32) (result i32))
-  (func (import "$root" "[future-close-readable-1]foo") (param i32))
+  (func (import "$root" "[future-close-readable-1]foo") (param i32 i32))
   (func (import "$root" "[future-close-writable-1]foo") (param i32 i32))
   (func (import "foo:foo/bar" "[future-new-1]foo") (result i32))
   (func (import "foo:foo/bar" "[future-read-1]foo") (param i32 i32) (result i32))
   (func (import "foo:foo/bar" "[future-write-1]foo") (param i32 i32) (result i32))
   (func (import "foo:foo/bar" "[future-cancel-read-1]foo") (param i32) (result i32))
   (func (import "foo:foo/bar" "[future-cancel-write-1]foo") (param i32) (result i32))
-  (func (import "foo:foo/bar" "[future-close-readable-1]foo") (param i32))
+  (func (import "foo:foo/bar" "[future-close-readable-1]foo") (param i32 i32))
   (func (import "foo:foo/bar" "[future-close-writable-1]foo") (param i32 i32))
   (func (import "[export]$root" "[stream-new-2]foo") (result i32))
   (func (import "[export]$root" "[stream-read-2]foo") (param i32 i32 i32) (result i32))
   (func (import "[export]$root" "[stream-write-2]foo") (param i32 i32 i32) (result i32))
   (func (import "[export]$root" "[stream-cancel-read-2]foo") (param i32) (result i32))
   (func (import "[export]$root" "[stream-cancel-write-2]foo") (param i32) (result i32))
-  (func (import "[export]$root" "[stream-close-readable-2]foo") (param i32))
+  (func (import "[export]$root" "[stream-close-readable-2]foo") (param i32 i32))
   (func (import "[export]$root" "[stream-close-writable-2]foo") (param i32 i32))
   (func (import "[export]foo:foo/bar" "[stream-new-2]foo") (result i32))
   (func (import "[export]foo:foo/bar" "[stream-read-2]foo") (param i32 i32 i32) (result i32))
   (func (import "[export]foo:foo/bar" "[stream-write-2]foo") (param i32 i32 i32) (result i32))
   (func (import "[export]foo:foo/bar" "[stream-cancel-read-2]foo") (param i32) (result i32))
   (func (import "[export]foo:foo/bar" "[stream-cancel-write-2]foo") (param i32) (result i32))
-  (func (import "[export]foo:foo/bar" "[stream-close-readable-2]foo") (param i32))
+  (func (import "[export]foo:foo/bar" "[stream-close-readable-2]foo") (param i32 i32))
   (func (import "[export]foo:foo/bar" "[stream-close-writable-2]foo") (param i32 i32))
   (func (import "[export]$root" "[future-new-0]foo") (result i32))
   (func (import "[export]$root" "[future-read-0]foo") (param i32 i32) (result i32))
   (func (import "[export]$root" "[future-write-0]foo") (param i32 i32) (result i32))
   (func (import "[export]$root" "[future-cancel-read-0]foo") (param i32) (result i32))
   (func (import "[export]$root" "[future-cancel-write-0]foo") (param i32) (result i32))
-  (func (import "[export]$root" "[future-close-readable-0]foo") (param i32))
+  (func (import "[export]$root" "[future-close-readable-0]foo") (param i32 i32))
   (func (import "[export]$root" "[future-close-writable-0]foo") (param i32 i32))
   (func (import "[export]foo:foo/bar" "[future-new-0]foo") (result i32))
   (func (import "[export]foo:foo/bar" "[future-read-0]foo") (param i32 i32) (result i32))
   (func (import "[export]foo:foo/bar" "[future-write-0]foo") (param i32 i32) (result i32))
   (func (import "[export]foo:foo/bar" "[future-cancel-read-0]foo") (param i32) (result i32))
   (func (import "[export]foo:foo/bar" "[future-cancel-write-0]foo") (param i32) (result i32))
-  (func (import "[export]foo:foo/bar" "[future-close-readable-0]foo") (param i32))
+  (func (import "[export]foo:foo/bar" "[future-close-readable-0]foo") (param i32 i32))
   (func (import "[export]foo:foo/bar" "[future-close-writable-0]foo") (param i32 i32))
   (func (import "[export]$root" "[future-new-1]foo") (result i32))
   (func (import "[export]$root" "[future-read-1]foo") (param i32 i32) (result i32))
   (func (import "[export]$root" "[future-write-1]foo") (param i32 i32) (result i32))
   (func (import "[export]$root" "[future-cancel-read-1]foo") (param i32) (result i32))
   (func (import "[export]$root" "[future-cancel-write-1]foo") (param i32) (result i32))
-  (func (import "[export]$root" "[future-close-readable-1]foo") (param i32))
+  (func (import "[export]$root" "[future-close-readable-1]foo") (param i32 i32))
   (func (import "[export]$root" "[future-close-writable-1]foo") (param i32 i32))
   (func (import "[export]foo:foo/bar" "[future-new-1]foo") (result i32))
   (func (import "[export]foo:foo/bar" "[future-read-1]foo") (param i32 i32) (result i32))
   (func (import "[export]foo:foo/bar" "[future-write-1]foo") (param i32 i32) (result i32))
   (func (import "[export]foo:foo/bar" "[future-cancel-read-1]foo") (param i32) (result i32))
   (func (import "[export]foo:foo/bar" "[future-cancel-write-1]foo") (param i32) (result i32))
-  (func (import "[export]foo:foo/bar" "[future-close-readable-1]foo") (param i32))
+  (func (import "[export]foo:foo/bar" "[future-close-readable-1]foo") (param i32 i32))
   (func (import "[export]foo:foo/bar" "[future-close-writable-1]foo") (param i32 i32))
   (func (export "[async-stackful]foo") (param i32 i32) unreachable)
   (func (export "[async-stackful]foo:foo/bar#foo") (param i32 i32) unreachable)
diff --git a/tests/cli/add-metadata-merge-sections.wat.stdout b/tests/cli/add-metadata-merge-sections.wat.stdout
index 49ed566d..c6491c6f 100644
--- a/tests/cli/add-metadata-merge-sections.wat.stdout
+++ b/tests/cli/add-metadata-merge-sections.wat.stdout
@@ -3,10 +3,10 @@
 ╞══════════╪═══════════╡
 │ kind     ┆ module    │
 ├╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌┤
-│ name     ┆ <unknown> │
-├╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌┤
 │ range    ┆ 0x0..0x36 │
 ├╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌┤
+│ name     ┆ <unknown> │
+├╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌┤
 │ language ┆ foo [3]   │
 ├╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌┤
 │ language ┆ bar [1]   │
diff --git a/tests/cli/add-metadata-overwrite-name.wat.stdout b/tests/cli/add-metadata-overwrite-name.wat.stdout
index 6803d701..3b5e74ed 100644
--- a/tests/cli/add-metadata-overwrite-name.wat.stdout
+++ b/tests/cli/add-metadata-overwrite-name.wat.stdout
@@ -3,7 +3,7 @@
 ╞═══════╪═══════════╡
 │ kind  ┆ module    │
 ├╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌┤
-│ name  ┆ foo       │
-├╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌┤
 │ range ┆ 0x0..0x15 │
+├╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌┤
+│ name  ┆ foo       │
 ╰───────┴───────────╯
diff --git a/tests/cli/add-metadata.wat.stdout b/tests/cli/add-metadata.wat.stdout
index b83255d9..3e88493c 100644
--- a/tests/cli/add-metadata.wat.stdout
+++ b/tests/cli/add-metadata.wat.stdout
@@ -3,10 +3,10 @@
 ╞══════════════╪════════════╡
 │ kind         ┆ module     │
 ├╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌┤
-│ name         ┆ foo        │
-├╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌┤
 │ range        ┆ 0x0..0x54  │
 ├╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌┤
+│ name         ┆ foo        │
+├╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌┤
 │ language     ┆ bar [1]    │
 ├╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌┤
 │ processed-by ┆ baz [1]    │
diff --git a/tests/cli/metadata-add-component.wat.stdout b/tests/cli/metadata-add-component.wat.stdout
index 72c06737..f0d29b40 100644
--- a/tests/cli/metadata-add-component.wat.stdout
+++ b/tests/cli/metadata-add-component.wat.stdout
@@ -3,10 +3,10 @@
 ╞══════════╪═══════════╡
 │ kind     ┆ component │
 ├╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌┤
-│ name     ┆ foo       │
-├╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌┤
 │ range    ┆ 0x0..0x65 │
 ├╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌┤
+│ name     ┆ foo       │
+├╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌┤
 │ language ┆ foo [1]   │
 ╰──────────┴───────────╯
 ╭───────┬───────────╮
@@ -14,7 +14,7 @@
 ╞═══════╪═══════════╡
 │ kind  ┆ module    │
 ├╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌┤
-│ name  ┆ <unknown> │
-├╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌┤
 │ range ┆ 0xa..0x31 │
+├╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌┤
+│ name  ┆ <unknown> │
 ╰───────┴───────────╯
diff --git a/tests/cli/metadata-component.wat.stdout b/tests/cli/metadata-component.wat.stdout
index d262ff85..5dd1cdb2 100644
--- a/tests/cli/metadata-component.wat.stdout
+++ b/tests/cli/metadata-component.wat.stdout
@@ -3,25 +3,25 @@
 ╞═══════╪═══════════╡
 │ kind  ┆ component │
 ├╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌┤
-│ name  ┆ my-name   │
-├╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌┤
 │ range ┆ 0x0..0x88 │
+├╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌┤
+│ name  ┆ my-name   │
 ╰───────┴───────────╯
 ╭───────┬───────────╮
 │ KIND  ┆ VALUE     │
 ╞═══════╪═══════════╡
 │ kind  ┆ module    │
 ├╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌┤
-│ name  ┆ submodule │
-├╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌┤
 │ range ┆ 0xa..0x25 │
+├╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌┤
+│ name  ┆ submodule │
 ╰───────┴───────────╯
 ╭───────┬───────────────────╮
 │ KIND  ┆ VALUE             │
 ╞═══════╪═══════════════════╡
 │ kind  ┆ module            │
 ├╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
-│ name  ┆ another submodule │
-├╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
 │ range ┆ 0x27..0x4a        │
+├╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
+│ name  ┆ another submodule │
 ╰───────┴───────────────────╯
diff --git a/tests/cli/metadata.wat.stdout b/tests/cli/metadata.wat.stdout
index 9dc357ab..4919b01d 100644
--- a/tests/cli/metadata.wat.stdout
+++ b/tests/cli/metadata.wat.stdout
@@ -3,7 +3,7 @@
 ╞═══════╪═══════════╡
 │ kind  ┆ module    │
 ├╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌┤
-│ name  ┆ <unknown> │
-├╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌┤
 │ range ┆ 0x0..0x8  │
+├╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌┤
+│ name  ┆ <unknown> │
 ╰───────┴───────────╯
diff --git a/tests/local/component-model-async/futures.wast b/tests/local/component-model-async/futures.wast
index 89678f25..a003b586 100644
--- a/tests/local/component-model-async/futures.wast
+++ b/tests/local/component-model-async/futures.wast
@@ -169,7 +169,7 @@
 ;; future.close-readable
 (component
   (core module $m
-    (import "" "future.close-readable" (func $future-close-readable (param i32)))
+    (import "" "future.close-readable" (func $future-close-readable (param i32 i32)))
   )
   (type $future-type (future u8))
   (core func $future-close-readable (canon future.close-readable $future-type))
@@ -180,7 +180,7 @@
 (assert_invalid
   (component
     (core module $m
-      (import "" "future.close-readable" (func $future-close-readable (param i32 i32) (result i32)))
+      (import "" "future.close-readable" (func $future-close-readable (param i32) (result i32)))
     )
     (type $future-type (future u8))
     (core func $future-close-readable (canon future.close-readable $future-type))
diff --git a/tests/local/component-model-async/streams.wast b/tests/local/component-model-async/streams.wast
index 0606c1c9..b71991ad 100644
--- a/tests/local/component-model-async/streams.wast
+++ b/tests/local/component-model-async/streams.wast
@@ -169,7 +169,7 @@
 ;; stream.close-readable
 (component
   (core module $m
-    (import "" "stream.close-readable" (func $stream-close-readable (param i32)))
+    (import "" "stream.close-readable" (func $stream-close-readable (param i32 i32)))
   )
   (type $stream-type (stream u8))
   (core func $stream-close-readable (canon stream.close-readable $stream-type))
@@ -180,7 +180,7 @@
 (assert_invalid
   (component
     (core module $m
-      (import "" "stream.close-readable" (func $stream-close-readable (param i32 i32) (result i32)))
+      (import "" "stream.close-readable" (func $stream-close-readable (param i32) (result i32)))
     )
     (type $stream-type (stream u8))
     (core func $stream-close-readable (canon stream.close-readable $stream-type))
diff --git a/tests/snapshots/local/component-model-async/futures.wast/13.print b/tests/snapshots/local/component-model-async/futures.wast/13.print
index 77546833..9ba2e601 100644
--- a/tests/snapshots/local/component-model-async/futures.wast/13.print
+++ b/tests/snapshots/local/component-model-async/futures.wast/13.print
@@ -1,6 +1,6 @@
 (component
   (core module $m (;0;)
-    (type (;0;) (func (param i32)))
+    (type (;0;) (func (param i32 i32)))
     (import "" "future.close-readable" (func $future-close-readable (;0;) (type 0)))
   )
   (type $future-type (;0;) (future u8))
diff --git a/tests/snapshots/local/component-model-async/streams.wast/13.print b/tests/snapshots/local/component-model-async/streams.wast/13.print
index 55c45e4b..d50386ff 100644
--- a/tests/snapshots/local/component-model-async/streams.wast/13.print
+++ b/tests/snapshots/local/component-model-async/streams.wast/13.print
@@ -1,6 +1,6 @@
 (component
   (core module $m (;0;)
-    (type (;0;) (func (param i32)))
+    (type (;0;) (func (param i32 i32)))
     (import "" "stream.close-readable" (func $stream-close-readable (;0;) (type 0)))
   )
   (type $stream-type (;0;) (stream u8))