Repository: bytecodealliance/wasm-tools
Pull request #2118 (2025-03-28 21:49:06)

Define component names subsection for core tag names
This allows components with named core tags to be roundtripped through the binary format.

0x04 is already allocated as CORE_TAG_SORT in https://github.com/WebAssembly/component-model/blob/main/design/mvp/Binary.md#name-section


Patch:
diff --git a/crates/wasm-encoder/src/reencode/component.rs b/crates/wasm-encoder/src/reencode/component.rs
index f920065e..33e7d81c 100644
--- a/crates/wasm-encoder/src/reencode/component.rs
+++ b/crates/wasm-encoder/src/reencode/component.rs
@@ -1393,6 +1393,9 @@ pub mod component_utils {
             wasmparser::ComponentName::CoreTables(map) => {
                 names.core_tables(&name_map(map, |i| reencoder.table_index(i))?);
             }
+            wasmparser::ComponentName::CoreTags(map) => {
+                names.core_tags(&name_map(map, |i| reencoder.tag_index(i))?);
+            }
             wasmparser::ComponentName::CoreModules(map) => {
                 names.core_modules(&name_map(map, |i| reencoder.module_index(i))?);
             }
diff --git a/crates/wasm-metadata/src/names/component.rs b/crates/wasm-metadata/src/names/component.rs
index 7b0d93c6..530ca56d 100644
--- a/crates/wasm-metadata/src/names/component.rs
+++ b/crates/wasm-metadata/src/names/component.rs
@@ -81,6 +81,7 @@ impl<'a> ComponentNames<'a> {
                 wasmparser::ComponentName::CoreGlobals(m) => section.core_globals(&name_map(&m)?),
                 wasmparser::ComponentName::CoreMemories(m) => section.core_memories(&name_map(&m)?),
                 wasmparser::ComponentName::CoreTables(m) => section.core_tables(&name_map(&m)?),
+                wasmparser::ComponentName::CoreTags(m) => section.core_tags(&name_map(&m)?),
                 wasmparser::ComponentName::CoreModules(m) => section.core_modules(&name_map(&m)?),
                 wasmparser::ComponentName::CoreInstances(m) => {
                     section.core_instances(&name_map(&m)?)
diff --git a/crates/wasmparser/src/readers/component/names.rs b/crates/wasmparser/src/readers/component/names.rs
index 39661cbd..44ec64ad 100644
--- a/crates/wasmparser/src/readers/component/names.rs
+++ b/crates/wasmparser/src/readers/component/names.rs
@@ -17,6 +17,7 @@ pub enum ComponentName<'a> {
     CoreGlobals(NameMap<'a>),
     CoreMemories(NameMap<'a>),
     CoreTables(NameMap<'a>),
+    CoreTags(NameMap<'a>),
     CoreModules(NameMap<'a>),
     CoreInstances(NameMap<'a>),
     CoreTypes(NameMap<'a>),
@@ -63,6 +64,7 @@ impl<'a> Subsection<'a> for ComponentName<'a> {
                         0x01 => ComponentName::CoreTables,
                         0x02 => ComponentName::CoreMemories,
                         0x03 => ComponentName::CoreGlobals,
+                        0x04 => ComponentName::CoreTags,
                         0x10 => ComponentName::CoreTypes,
                         0x11 => ComponentName::CoreModules,
                         0x12 => ComponentName::CoreInstances,
diff --git a/crates/wasmprinter/src/component.rs b/crates/wasmprinter/src/component.rs
index 03a9d576..ee50cbaa 100644
--- a/crates/wasmprinter/src/component.rs
+++ b/crates/wasmprinter/src/component.rs
@@ -29,6 +29,7 @@ impl Printer<'_, '_> {
                 ComponentName::CoreGlobals(n) => {
                     name_map(&mut state.core.global_names, n, "core-global")?
                 }
+                ComponentName::CoreTags(n) => name_map(&mut state.core.tag_names, n, "core-tag")?,
                 ComponentName::CoreModules(n) => {
                     name_map(&mut state.core.module_names, n, "core-module")?
                 }
diff --git a/src/bin/wasm-tools/dump.rs b/src/bin/wasm-tools/dump.rs
index ce1d61a5..a6daafb9 100644
--- a/src/bin/wasm-tools/dump.rs
+++ b/src/bin/wasm-tools/dump.rs
@@ -685,6 +685,7 @@ impl<'a> Dump<'a> {
             ComponentName::CoreTables(n) => self.print_name_map("core table", n)?,
             ComponentName::CoreGlobals(n) => self.print_name_map("core global", n)?,
             ComponentName::CoreMemories(n) => self.print_name_map("core memory", n)?,
+            ComponentName::CoreTags(n) => self.print_name_map("core tag", n)?,
             ComponentName::CoreInstances(n) => self.print_name_map("core instance", n)?,
             ComponentName::CoreModules(n) => self.print_name_map("core module", n)?,
             ComponentName::CoreTypes(n) => self.print_name_map("core type", n)?,


Test patch:
diff --git a/tests/cli/component-model/gated-tags.wast b/tests/cli/component-model/gated-tags.wast
index 1ff92fa2..b728bb66 100644
--- a/tests/cli/component-model/gated-tags.wast
+++ b/tests/cli/component-model/gated-tags.wast
@@ -1,4 +1,4 @@
-;; RUN: wast --features=-exceptions %
+;; RUN: wast --features=-exceptions --assert default --snapshot tests/snapshots %
 
 (assert_invalid
   (component
diff --git a/tests/cli/component-model/tags.wast b/tests/cli/component-model/tags.wast
index 9f8d754b..5c70d3ab 100644
--- a/tests/cli/component-model/tags.wast
+++ b/tests/cli/component-model/tags.wast
@@ -1,4 +1,4 @@
-;; RUN: wast %
+;; RUN: wast --assert default --snapshot tests/snapshots %
 
 (assert_invalid
   (component
diff --git a/tests/snapshots/cli/component-model/gated-tags.wast.json b/tests/snapshots/cli/component-model/gated-tags.wast.json
new file mode 100644
index 00000000..01f06de0
--- /dev/null
+++ b/tests/snapshots/cli/component-model/gated-tags.wast.json
@@ -0,0 +1,19 @@
+{
+  "source_filename": "tests/cli/component-model/gated-tags.wast",
+  "commands": [
+    {
+      "type": "assert_invalid",
+      "line": 4,
+      "filename": "gated-tags.0.wasm",
+      "module_type": "binary",
+      "text": "exceptions proposal not enabled"
+    },
+    {
+      "type": "assert_invalid",
+      "line": 12,
+      "filename": "gated-tags.1.wasm",
+      "module_type": "binary",
+      "text": "exceptions proposal not enabled"
+    }
+  ]
+}
\ No newline at end of file
diff --git a/tests/snapshots/cli/component-model/tags.wast.json b/tests/snapshots/cli/component-model/tags.wast.json
new file mode 100644
index 00000000..d268a1d5
--- /dev/null
+++ b/tests/snapshots/cli/component-model/tags.wast.json
@@ -0,0 +1,31 @@
+{
+  "source_filename": "tests/cli/component-model/tags.wast",
+  "commands": [
+    {
+      "type": "assert_invalid",
+      "line": 4,
+      "filename": "tags.0.wasm",
+      "module_type": "binary",
+      "text": "export `` for core instance 0 is not a tag"
+    },
+    {
+      "type": "module",
+      "line": 11,
+      "filename": "tags.1.wasm",
+      "module_type": "binary"
+    },
+    {
+      "type": "module",
+      "line": 17,
+      "filename": "tags.2.wasm",
+      "module_type": "binary"
+    },
+    {
+      "type": "assert_invalid",
+      "line": 24,
+      "filename": "tags.3.wasm",
+      "module_type": "binary",
+      "text": "unknown tag 0"
+    }
+  ]
+}
\ No newline at end of file
diff --git a/tests/snapshots/cli/component-model/tags.wast/1.print b/tests/snapshots/cli/component-model/tags.wast/1.print
new file mode 100644
index 00000000..545df1e2
--- /dev/null
+++ b/tests/snapshots/cli/component-model/tags.wast/1.print
@@ -0,0 +1,9 @@
+(component
+  (core module $m (;0;)
+    (type (;0;) (func))
+    (tag (;0;) (type 0))
+    (export "" (tag 0))
+  )
+  (core instance $i (;0;) (instantiate $m))
+  (alias core export $i "" (core tag $t (;0;)))
+)
diff --git a/tests/snapshots/cli/component-model/tags.wast/2.print b/tests/snapshots/cli/component-model/tags.wast/2.print
new file mode 100644
index 00000000..13a7aa76
--- /dev/null
+++ b/tests/snapshots/cli/component-model/tags.wast/2.print
@@ -0,0 +1,12 @@
+(component
+  (core module $m (;0;)
+    (type (;0;) (func))
+    (tag (;0;) (type 0))
+    (export "" (tag 0))
+  )
+  (core instance $i (;0;) (instantiate $m))
+  (alias core export $i "" (core tag (;0;)))
+  (core instance (;1;)
+    (export "" (tag 0))
+  )
+)