Repository: bytecodealliance/wasm-tools
Pull request #1438 (2024-03-07 20:15:22)

Make self argument for guest exported resources a Pointer (rep)
This solution feels inelegant, ideally you would distinguish between imported and exported resource Handles and then use either I32 or Pointer in abi::push_flat().

But it clearly fixes the problem of the self argument in respect to that rep is 64 bit on wasm64 (and potential native uses).

Apart from removing the related casting in https://github.com/bytecodealliance/wit-bindgen/blob/main/crates/rust/src/bindgen.rs#L444 and some linker symbol changes in wit-bindgen this is all which is needed to enable native (e.g. x86_64) WIT interfaces.

See https://github.com/bytecodealliance/wit-bindgen/blob/73e5c68d88714e5073bfa93836f8dd6d456b4b0b/crates/rust/src/interface.rs#L581-L589 for above mentioned linker symbol code.

alexcrichton: Thanks for this! I agree that this isn't the best solution but should at least get the job done for exported resources. To be clear this isn't a complete solution since borrowed-handles-to-exported-resources can show up anywhere, not just as the first argument to an exported method. The first argument of exported methods, however, are guaranteed to be exported resources since otherwise the component wouldn't validate.

Fixing this "for real" I think is not in the cards at this time. There needs to be the ability to answer the question of "is this resource exported" and that's not a question we can answer at this time because the same type is both used for imports and exports. That means that more contextual information is needed to answer the question of whether it's exported or not, and I don't think that this method can reasonably take it at this time.

All that being said, some requests if you're ok with it:

* Can you assert that the previous value was `I32`?
* Can you add a comment, with a `// TODO` or similar, about why this transformation is guaranteed to be correct as well as how it's best to fix this in the future since it's not a complete solution?
cpetig: I hope the TODO is understandable.

And of course I have to correct myself:
I do have a working example of compiling a Rust project to a shared library and accessing it via a WIT interface, but for lists and string lengths the offset is still wrong, as well as the size and alignment of ret areas. So additional work is needed for these.
cpetig: Oh, I see, I used an unstable Rust feature ... going to fix it.

Patch:
diff --git a/crates/wasmprinter/src/operator.rs b/crates/wasmprinter/src/operator.rs
index cbd54341..d91ee609 100644
--- a/crates/wasmprinter/src/operator.rs
+++ b/crates/wasmprinter/src/operator.rs
@@ -142,26 +142,47 @@ impl<'a, 'b> PrintOperator<'a, 'b> {
                 // in the case of shadowing, which would be the wrong behavior
                 // here. All that can be done is to print the index down below
                 // instead.
-                let name = name.and_then(|name| {
-                    for other_label in self.label_indices[i as usize..].iter() {
+                let name_conflict = name.is_some()
+                    && self.label_indices[i as usize..].iter().any(|other_label| {
                         let key = (self.state.core.funcs, *other_label);
                         if let Some(other) = self.state.core.label_names.index_to_name.get(&key) {
-                            if name.name == other.name {
-                                return None;
+                            if name.unwrap().name == other.name {
+                                return true;
                             }
                         }
-                    }
-                    Some(name)
-                });
+                        false
+                    });
 
                 match name {
-                    Some(name) => name.write(&mut self.printer.result),
+                    // Only print the name if one is found and there's also no
+                    // name conflict.
+                    Some(name) if !name_conflict => name.write(&mut self.printer.result),
+
+                    // If there's no name conflict, and we're synthesizing
+                    // names, and this isn't targetting the function itself then
+                    // print a synthesized names.
+                    //
+                    // Note that synthesized label names don't handle the
+                    // function itself, so i==0, branching to a function label,
+                    // is not supported and otherwise labels are offset by 1.
+                    None if !name_conflict && self.printer.name_unnamed && i > 0 => {
+                        write!(self.result(), "$#label{}", i - 1)?
+                    }
 
-                    None if self.printer.name_unnamed => write!(self.result(), "$#label{i}")?,
+                    _ => {
+                        // Last-ditch resort, we gotta print the index.
+                        write!(self.result(), "{depth}")?;
 
-                    // If this label has some name also print its pseudo-name as
-                    // `@N` to help match things up in the text format.
-                    None => write!(self.result(), "{depth} (;@{i};)")?,
+                        // Unnamed labels have helpful `@N` labels printed for
+                        // them so also try to print where this index is going
+                        // (label-wise). Don't do this for a name conflict
+                        // though because we wouldn't have printed the numbered
+                        // label, and also don't do it for the function itself
+                        // since the function has no label we can synthesize.
+                        if !name_conflict && i > 0 {
+                            write!(self.result(), " (;@{i};)")?;
+                        }
+                    }
                 }
             }
 
diff --git a/crates/wast/src/core/memory.rs b/crates/wast/src/core/memory.rs
index eb1baa1a..436afa94 100644
--- a/crates/wast/src/core/memory.rs
+++ b/crates/wast/src/core/memory.rs
@@ -133,7 +133,7 @@ impl<'a> Parse<'a> for Data<'a> {
         let id = parser.parse()?;
         let name = parser.parse()?;
 
-        let kind = if parser.peek::<&[u8]>()? {
+        let kind = if parser.peek::<&[u8]>()? || parser.peek::<RParen>()? {
             DataKind::Passive
 
         // ... and otherwise we must be attached to a particular memory as well
diff --git a/crates/wast/src/token.rs b/crates/wast/src/token.rs
index 9dd15f97..e5a3d9ba 100644
--- a/crates/wast/src/token.rs
+++ b/crates/wast/src/token.rs
@@ -677,6 +677,22 @@ impl Peek for LParen {
     }
 }
 
+/// A convenience type to use with [`Parser::peek`](crate::parser::Parser::peek)
+/// to see if the next token is the end of an s-expression.
+pub struct RParen {
+    _priv: (),
+}
+
+impl Peek for RParen {
+    fn peek(cursor: Cursor<'_>) -> Result<bool> {
+        cursor.peek_rparen()
+    }
+
+    fn display() -> &'static str {
+        "right paren"
+    }
+}
+
 #[cfg(test)]
 mod tests {
     #[test]
diff --git a/crates/wit-parser/src/abi.rs b/crates/wit-parser/src/abi.rs
index 1c383384..1ea01acc 100644
--- a/crates/wit-parser/src/abi.rs
+++ b/crates/wit-parser/src/abi.rs
@@ -148,6 +148,20 @@ impl Resolve {
             params.truncate(0);
             params.push(WasmType::Pointer);
             indirect_params = true;
+        } else {
+            if matches!(
+                (&func.kind, variant),
+                (crate::FunctionKind::Method(_), AbiVariant::GuestExport)
+            ) {
+                // Guest exported methods always receive resource rep as first argument
+                //
+                // TODO: Ideally you would distinguish between imported and exported
+                // resource Handles and then use either I32 or Pointer in abi::push_flat().
+                // But this contextual information isn't available, yet.
+                // See https://github.com/bytecodealliance/wasm-tools/pull/1438 for more details.
+                assert!(matches!(params[0], WasmType::I32));
+                params[0] = WasmType::Pointer;
+            }
         }
 
         let mut results = Vec::new();
diff --git a/crates/wit-parser/src/resolve.rs b/crates/wit-parser/src/resolve.rs
index 504c56f7..58bf6179 100644
--- a/crates/wit-parser/src/resolve.rs
+++ b/crates/wit-parser/src/resolve.rs
@@ -236,10 +236,11 @@ impl Resolve {
         for dep in entries {
             let path = dep.path();
 
-            let pkg = if dep.file_type()?.is_dir() {
-                // If this entry is a directory then always parse it as an
-                // `UnresolvedPackage` since it's intentional to not support
-                // recursive `deps` directories.
+            let pkg = if dep.file_type()?.is_dir() || path.metadata()?.is_dir() {
+                // If this entry is a directory or a symlink point to a
+                // directory then always parse it as an `UnresolvedPackage`
+                // since it's intentional to not support recursive `deps`
+                // directories.
                 UnresolvedPackage::parse_dir(&path)
                     .with_context(|| format!("failed to parse package: {}", path.display()))?
             } else {


Test patch:
diff --git a/crates/wasmprinter/tests/all.rs b/crates/wasmprinter/tests/all.rs
index 485fbe38..d783d6fa 100644
--- a/crates/wasmprinter/tests/all.rs
+++ b/crates/wasmprinter/tests/all.rs
@@ -202,7 +202,7 @@ fn label_shadowing_block_confusion() {
         (func (;0;) (type 0)
           block $a
             block $a
-              br 1 (;@1;)
+              br 1
             end
           end
         )
diff --git a/tests/cli/dump/simple.wat b/tests/cli/dump/simple.wat
index a4906efd..8922edc5 100644
--- a/tests/cli/dump/simple.wat
+++ b/tests/cli/dump/simple.wat
@@ -17,5 +17,6 @@
   (func (local i32) i32.const 0)
   (data (i32.const 8) "y")
   (data "x")
+  (data)
   (@custom "name-of-section" "content")
 )
diff --git a/tests/cli/dump/simple.wat.stdout b/tests/cli/dump/simple.wat.stdout
index d94396db..cdd813ba 100644
--- a/tests/cli/dump/simple.wat.stdout
+++ b/tests/cli/dump/simple.wat.stdout
@@ -59,17 +59,19 @@
  0x60 | 01 7f       | 1 locals of type I32
  0x62 | 41 00       | i32_const value:0
  0x64 | 0b          | end
- 0x65 | 0b 0a       | data section
- 0x67 | 02          | 2 count
+ 0x65 | 0b 0c       | data section
+ 0x67 | 03          | 3 count
  0x68 | 00          | data memory[0]
  0x69 | 41 08       | i32_const value:8
  0x6b | 0b          | end
  0x6c |-------------| ... 1 bytes of data
  0x6e | 01 01       | data passive
  0x70 |-------------| ... 1 bytes of data
- 0x71 | 00 17       | custom section
- 0x73 | 0f 6e 61 6d | name: "name-of-section"
+ 0x71 | 01 00       | data passive
+ 0x73 |-------------| ... 0 bytes of data
+ 0x73 | 00 17       | custom section
+ 0x75 | 0f 6e 61 6d | name: "name-of-section"
       | 65 2d 6f 66
       | 2d 73 65 63
       | 74 69 6f 6e
- 0x83 |-------------| ... 7 bytes of data
+ 0x85 |-------------| ... 7 bytes of data
diff --git a/tests/cli/print-unnamed.wat b/tests/cli/print-unnamed.wat
new file mode 100644
index 00000000..33de1cbc
--- /dev/null
+++ b/tests/cli/print-unnamed.wat
@@ -0,0 +1,34 @@
+;; RUN: print --name-unnamed %
+
+(module
+  (func
+    (block $a
+      (block ;; unnamed
+        (block $c
+          i32.const 0
+          br_table $a 1 $c
+        )
+      )
+    )
+    (block $c
+      (block ;; unnamed
+        (block $a
+          i32.const 0
+          br_table $a 1 $c
+        )
+      )
+    )
+    (block $a ;; 3
+      (block $a ;; 2
+        (block $a ;; 1
+          i32.const 0
+          br_table
+            0 ;; -> a/1
+            1 ;; -> a/2
+            2 ;; -> a/3
+            3 ;; -> function label
+        )
+      )
+    )
+  )
+)
diff --git a/tests/cli/print-unnamed.wat.stdout b/tests/cli/print-unnamed.wat.stdout
new file mode 100644
index 00000000..ef3483ad
--- /dev/null
+++ b/tests/cli/print-unnamed.wat.stdout
@@ -0,0 +1,29 @@
+(module
+  (type $#type0 (;0;) (func))
+  (func $#func0 (;0;) (type $#type0)
+    block $a
+      block $#label1
+        block $c
+          i32.const 0
+          br_table $a $#label1 $c
+        end
+      end
+    end
+    block $c
+      block $#label1
+        block $a
+          i32.const 0
+          br_table $a $#label1 $c
+        end
+      end
+    end
+    block $a
+      block $a
+        block $a
+          i32.const 0
+          br_table $a 1 2 3
+        end
+      end
+    end
+  )
+)
diff --git a/tests/snapshots/local/br-confusion.wat.print b/tests/snapshots/local/br-confusion.wat.print
index d8e288e1..4b2bbd85 100644
--- a/tests/snapshots/local/br-confusion.wat.print
+++ b/tests/snapshots/local/br-confusion.wat.print
@@ -3,7 +3,7 @@
   (func (;0;) (type 0)
     block $a
       block $a
-        br 1 (;@1;)
+        br 1
       end
     end
   )
diff --git a/tests/snapshots/local/br_table_loop_multi.wat.print b/tests/snapshots/local/br_table_loop_multi.wat.print
index da5290cd..7e0bfb4f 100644
--- a/tests/snapshots/local/br_table_loop_multi.wat.print
+++ b/tests/snapshots/local/br_table_loop_multi.wat.print
@@ -6,7 +6,7 @@
     local.get 1
     loop (type 1) (param i32) ;; label = @1
       i32.const -458751
-      br_table 0 (;@1;) 1 (;@0;) 0 (;@1;)
+      br_table 0 (;@1;) 1 0 (;@1;)
       unreachable
     end
     unreachable
diff --git a/tests/snapshots/local/function-references/call_ref/br_on_null.wast/5.print b/tests/snapshots/local/function-references/call_ref/br_on_null.wast/5.print
index 1946ceac..a2f77bfe 100644
--- a/tests/snapshots/local/function-references/call_ref/br_on_null.wast/5.print
+++ b/tests/snapshots/local/function-references/call_ref/br_on_null.wast/5.print
@@ -5,17 +5,17 @@
   (type (;3;) (func (param externref)))
   (func (;0;) (type 1) (param $r (ref null $t))
     local.get $r
-    br_on_null 0 (;@0;)
+    br_on_null 0
     drop
   )
   (func (;1;) (type 2) (param $r funcref)
     local.get $r
-    br_on_null 0 (;@0;)
+    br_on_null 0
     drop
   )
   (func (;2;) (type 3) (param $r externref)
     local.get $r
-    br_on_null 0 (;@0;)
+    br_on_null 0
     drop
   )
 )
diff --git a/tests/snapshots/local/gc/type-subtyping.wast/17.print b/tests/snapshots/local/gc/type-subtyping.wast/17.print
index 269bc81a..98ebf663 100644
--- a/tests/snapshots/local/gc/type-subtyping.wast/17.print
+++ b/tests/snapshots/local/gc/type-subtyping.wast/17.print
@@ -71,46 +71,46 @@
       table.get 0
       ref.cast (ref $t2)
     end
-    br 0 (;@0;)
+    br 0
   )
   (func (;4;) (type 3)
     block (result (ref null $t1)) ;; label = @1
       i32.const 0
       call_indirect (type $t1)
     end
-    br 0 (;@0;)
+    br 0
   )
   (func (;5;) (type 3)
     block (result (ref null $t1)) ;; label = @1
       i32.const 0
       call_indirect (type $t2)
     end
-    br 0 (;@0;)
+    br 0
   )
   (func (;6;) (type 3)
     block (result (ref null $t1)) ;; label = @1
       i32.const 1
       call_indirect (type $t2)
     end
-    br 0 (;@0;)
+    br 0
   )
   (func (;7;) (type 3)
     i32.const 0
     table.get 0
     ref.cast (ref $t1)
-    br 0 (;@0;)
+    br 0
   )
   (func (;8;) (type 3)
     i32.const 0
     table.get 0
     ref.cast (ref $t2)
-    br 0 (;@0;)
+    br 0
   )
   (func (;9;) (type 3)
     i32.const 1
     table.get 0
     ref.cast (ref $t2)
-    br 0 (;@0;)
+    br 0
   )
   (table (;0;) 3 3 funcref)
   (export "run" (func 3))
diff --git a/tests/snapshots/local/unreachable-valid.wast/0.print b/tests/snapshots/local/unreachable-valid.wast/0.print
index 7a780164..3343348b 100644
--- a/tests/snapshots/local/unreachable-valid.wast/0.print
+++ b/tests/snapshots/local/unreachable-valid.wast/0.print
@@ -3,7 +3,7 @@
   (func (;0;) (type 0)
     f32.const 0x1p+0 (;=1;)
     f32.const 0x1p+1 (;=2;)
-    br 0 (;@0;)
+    br 0
     i32.add
     drop
   )
diff --git a/tests/snapshots/testsuite/binary.wast/108.print b/tests/snapshots/testsuite/binary.wast/108.print
index 5b782f46..7d6e8576 100644
--- a/tests/snapshots/testsuite/binary.wast/108.print
+++ b/tests/snapshots/testsuite/binary.wast/108.print
@@ -5,7 +5,7 @@
       i32.const 1
       if ;; label = @2
         i32.const 1
-        br_table 2 (;@0;)
+        br_table 2
       end
     end
   )
diff --git a/tests/snapshots/testsuite/br_if.wast/0.print b/tests/snapshots/testsuite/br_if.wast/0.print
index 6d1aff4d..a5c16483 100644
--- a/tests/snapshots/testsuite/br_if.wast/0.print
+++ b/tests/snapshots/testsuite/br_if.wast/0.print
@@ -161,7 +161,7 @@
     loop ;; label = @1
       call $dummy
       local.get 0
-      br_if 1 (;@0;)
+      br_if 1
     end
   )
   (func (;18;) (type 2) (result i32)
diff --git a/tests/snapshots/testsuite/br_table.wast/0.print b/tests/snapshots/testsuite/br_table.wast/0.print
index 2c3bf9be..e471a549 100644
--- a/tests/snapshots/testsuite/br_table.wast/0.print
+++ b/tests/snapshots/testsuite/br_table.wast/0.print
@@ -235,7 +235,7 @@
     loop (result i32) ;; label = @1
       i32.const 3
       i32.const 0
-      br_table 1 (;@0;) 1 (;@0;)
+      br_table 1 1
       i32.const 1
     end
   )
@@ -244,7 +244,7 @@
       call $dummy
       i32.const 4
       i32.const -1
-      br_table 1 (;@0;) 1 (;@0;) 1 (;@0;)
+      br_table 1 1 1
       i32.const 2
     end
   )
@@ -254,7 +254,7 @@
       call $dummy
       i32.const 5
       i32.const 1
-      br_table 1 (;@0;) 1 (;@0;) 1 (;@0;)
+      br_table 1 1 1
     end
   )
   (func (;23;) (type 2) (result i32)
diff --git a/tests/snapshots/testsuite/func.wast/0.print b/tests/snapshots/testsuite/func.wast/0.print
index df1b5e37..51702741 100644
--- a/tests/snapshots/testsuite/func.wast/0.print
+++ b/tests/snapshots/testsuite/func.wast/0.print
@@ -286,41 +286,41 @@
     return
   )
   (func (;74;) (type $sig)
-    br 0 (;@0;)
+    br 0
   )
   (func (;75;) (type $sig-2) (result i32)
     i32.const 79
-    br 0 (;@0;)
+    br 0
   )
   (func (;76;) (type 13) (result i64)
     i64.const 7979
-    br 0 (;@0;)
+    br 0
   )
   (func (;77;) (type 14) (result f32)
     f32.const 0x1.3f999ap+6 (;=79.9;)
-    br 0 (;@0;)
+    br 0
   )
   (func (;78;) (type 15) (result f64)
     f64.const 0x1.3f28f5c28f5c3p+6 (;=79.79;)
-    br 0 (;@0;)
+    br 0
   )
   (func (;79;) (type 10) (result i32 f64)
     i32.const 79
     f64.const 0x1.3f28f5c28f5c3p+6 (;=79.79;)
-    br 0 (;@0;)
+    br 0
   )
   (func (;80;) (type 21) (result i32 i32 i32)
     i32.const 1
     i32.const 2
     i32.const 3
-    br 0 (;@0;)
+    br 0
   )
   (func (;81;) (type $sig-2) (result i32)
     block (result i32) ;; label = @1
       call $dummy
       i32.const 77
     end
-    br 0 (;@0;)
+    br 0
   )
   (func (;82;) (type 22) (result i32 i64)
     block (type 22) (result i32 i64) ;; label = @1
@@ -328,16 +328,16 @@
       i32.const 1
       i64.const 2
     end
-    br 0 (;@0;)
+    br 0
   )
   (func (;83;) (type $sig-3) (param i32)
     local.get 0
-    br_if 0 (;@0;)
+    br_if 0
   )
   (func (;84;) (type 23) (param i32) (result i32)
     i32.const 50
     local.get 0
-    br_if 0 (;@0;)
+    br_if 0
     drop
     i32.const 51
   )
@@ -345,7 +345,7 @@
     i32.const 50
     i64.const 51
     local.get 0
-    br_if 0 (;@0;)
+    br_if 0
     drop
     drop
     i32.const 51
@@ -353,33 +353,33 @@
   )
   (func (;86;) (type $sig-3) (param i32)
     local.get 0
-    br_table 0 (;@0;) 0 (;@0;) 0 (;@0;)
+    br_table 0 0 0
   )
   (func (;87;) (type 23) (param i32) (result i32)
     i32.const 50
     local.get 0
-    br_table 0 (;@0;) 0 (;@0;)
+    br_table 0 0
     i32.const 51
   )
   (func (;88;) (type 24) (param i32) (result i32 i64)
     i32.const 50
     i64.const 51
     local.get 0
-    br_table 0 (;@0;) 0 (;@0;)
+    br_table 0 0
     i32.const 51
     i64.const 52
   )
   (func (;89;) (type $sig-3) (param i32)
     block ;; label = @1
       local.get 0
-      br_table 0 (;@1;) 1 (;@0;) 0 (;@1;)
+      br_table 0 (;@1;) 1 0 (;@1;)
     end
   )
   (func (;90;) (type 23) (param i32) (result i32)
     block (result i32) ;; label = @1
       i32.const 50
       local.get 0
-      br_table 0 (;@1;) 1 (;@0;) 0 (;@1;)
+      br_table 0 (;@1;) 1 0 (;@1;)
       i32.const 51
     end
     i32.const 2
@@ -390,7 +390,7 @@
       i32.const 50
       i32.const 51
       local.get 0
-      br_table 0 (;@1;) 1 (;@0;) 0 (;@1;)
+      br_table 0 (;@1;) 1 0 (;@1;)
       i32.const 51
       i32.const -3
     end
diff --git a/tests/snapshots/testsuite/proposals/exception-handling/binary.wast/108.print b/tests/snapshots/testsuite/proposals/exception-handling/binary.wast/108.print
index 5b782f46..7d6e8576 100644
--- a/tests/snapshots/testsuite/proposals/exception-handling/binary.wast/108.print
+++ b/tests/snapshots/testsuite/proposals/exception-handling/binary.wast/108.print
@@ -5,7 +5,7 @@
       i32.const 1
       if ;; label = @2
         i32.const 1
-        br_table 2 (;@0;)
+        br_table 2
       end
     end
   )
diff --git a/tests/snapshots/testsuite/proposals/exception-handling/try_table.wast/44.print b/tests/snapshots/testsuite/proposals/exception-handling/try_table.wast/44.print
index 897f88f8..d60ed2c8 100644
--- a/tests/snapshots/testsuite/proposals/exception-handling/try_table.wast/44.print
+++ b/tests/snapshots/testsuite/proposals/exception-handling/try_table.wast/44.print
@@ -2,29 +2,29 @@
   (type (;0;) (func))
   (type (;1;) (func (result exnref)))
   (func (;0;) (type 0)
-    try_table (catch $e 0 (;@0;)) (catch $e 0 (;@0;)) ;; label = @1
+    try_table (catch $e 0) (catch $e 0) ;; label = @1
     end
   )
   (func (;1;) (type 0)
-    try_table (catch_all 0 (;@0;)) (catch $e 0 (;@0;)) ;; label = @1
+    try_table (catch_all 0) (catch $e 0) ;; label = @1
     end
   )
   (func (;2;) (type 0)
-    try_table (catch_all 0 (;@0;)) (catch_all 0 (;@0;)) ;; label = @1
+    try_table (catch_all 0) (catch_all 0) ;; label = @1
     end
   )
   (func (;3;) (type 1) (result exnref)
-    try_table (catch_ref $e 0 (;@0;)) (catch_ref $e 0 (;@0;)) ;; label = @1
+    try_table (catch_ref $e 0) (catch_ref $e 0) ;; label = @1
     end
     unreachable
   )
   (func (;4;) (type 1) (result exnref)
-    try_table (catch_all_ref 0 (;@0;)) (catch_ref $e 0 (;@0;)) ;; label = @1
+    try_table (catch_all_ref 0) (catch_ref $e 0) ;; label = @1
     end
     unreachable
   )
   (func (;5;) (type 1) (result exnref)
-    try_table (catch_all_ref 0 (;@0;)) (catch_all_ref 0 (;@0;)) ;; label = @1
+    try_table (catch_all_ref 0) (catch_all_ref 0) ;; label = @1
     end
     unreachable
   )
diff --git a/tests/snapshots/testsuite/proposals/function-references/binary.wast/108.print b/tests/snapshots/testsuite/proposals/function-references/binary.wast/108.print
index 5b782f46..7d6e8576 100644
--- a/tests/snapshots/testsuite/proposals/function-references/binary.wast/108.print
+++ b/tests/snapshots/testsuite/proposals/function-references/binary.wast/108.print
@@ -5,7 +5,7 @@
       i32.const 1
       if ;; label = @2
         i32.const 1
-        br_table 2 (;@0;)
+        br_table 2
       end
     end
   )
diff --git a/tests/snapshots/testsuite/proposals/function-references/br_on_null.wast/5.print b/tests/snapshots/testsuite/proposals/function-references/br_on_null.wast/5.print
index 1946ceac..a2f77bfe 100644
--- a/tests/snapshots/testsuite/proposals/function-references/br_on_null.wast/5.print
+++ b/tests/snapshots/testsuite/proposals/function-references/br_on_null.wast/5.print
@@ -5,17 +5,17 @@
   (type (;3;) (func (param externref)))
   (func (;0;) (type 1) (param $r (ref null $t))
     local.get $r
-    br_on_null 0 (;@0;)
+    br_on_null 0
     drop
   )
   (func (;1;) (type 2) (param $r funcref)
     local.get $r
-    br_on_null 0 (;@0;)
+    br_on_null 0
     drop
   )
   (func (;2;) (type 3) (param $r externref)
     local.get $r
-    br_on_null 0 (;@0;)
+    br_on_null 0
     drop
   )
 )
diff --git a/tests/snapshots/testsuite/proposals/function-references/br_table.wast/0.print b/tests/snapshots/testsuite/proposals/function-references/br_table.wast/0.print
index c3603f18..69ccd9ac 100644
--- a/tests/snapshots/testsuite/proposals/function-references/br_table.wast/0.print
+++ b/tests/snapshots/testsuite/proposals/function-references/br_table.wast/0.print
@@ -236,7 +236,7 @@
     loop (result i32) ;; label = @1
       i32.const 3
       i32.const 0
-      br_table 1 (;@0;) 1 (;@0;)
+      br_table 1 1
       i32.const 1
     end
   )
@@ -245,7 +245,7 @@
       call $dummy
       i32.const 4
       i32.const -1
-      br_table 1 (;@0;) 1 (;@0;) 1 (;@0;)
+      br_table 1 1 1
       i32.const 2
     end
   )
@@ -255,7 +255,7 @@
       call $dummy
       i32.const 5
       i32.const 1
-      br_table 1 (;@0;) 1 (;@0;) 1 (;@0;)
+      br_table 1 1 1
     end
   )
   (func (;23;) (type 2) (result i32)
diff --git a/tests/snapshots/testsuite/proposals/function-references/func.wast/0.print b/tests/snapshots/testsuite/proposals/function-references/func.wast/0.print
index 36cd194c..87259d3a 100644
--- a/tests/snapshots/testsuite/proposals/function-references/func.wast/0.print
+++ b/tests/snapshots/testsuite/proposals/function-references/func.wast/0.print
@@ -287,41 +287,41 @@
     return
   )
   (func (;74;) (type $sig)
-    br 0 (;@0;)
+    br 0
   )
   (func (;75;) (type $sig-2) (result i32)
     i32.const 79
-    br 0 (;@0;)
+    br 0
   )
   (func (;76;) (type 13) (result i64)
     i64.const 7979
-    br 0 (;@0;)
+    br 0
   )
   (func (;77;) (type 14) (result f32)
     f32.const 0x1.3f999ap+6 (;=79.9;)
-    br 0 (;@0;)
+    br 0
   )
   (func (;78;) (type 15) (result f64)
     f64.const 0x1.3f28f5c28f5c3p+6 (;=79.79;)
-    br 0 (;@0;)
+    br 0
   )
   (func (;79;) (type 10) (result i32 f64)
     i32.const 79
     f64.const 0x1.3f28f5c28f5c3p+6 (;=79.79;)
-    br 0 (;@0;)
+    br 0
   )
   (func (;80;) (type 21) (result i32 i32 i32)
     i32.const 1
     i32.const 2
     i32.const 3
-    br 0 (;@0;)
+    br 0
   )
   (func (;81;) (type $sig-2) (result i32)
     block (result i32) ;; label = @1
       call $dummy
       i32.const 77
     end
-    br 0 (;@0;)
+    br 0
   )
   (func (;82;) (type 22) (result i32 i64)
     block (type 22) (result i32 i64) ;; label = @1
@@ -329,16 +329,16 @@
       i32.const 1
       i64.const 2
     end
-    br 0 (;@0;)
+    br 0
   )
   (func (;83;) (type $sig-3) (param i32)
     local.get 0
-    br_if 0 (;@0;)
+    br_if 0
   )
   (func (;84;) (type 23) (param i32) (result i32)
     i32.const 50
     local.get 0
-    br_if 0 (;@0;)
+    br_if 0
     drop
     i32.const 51
   )
@@ -346,7 +346,7 @@
     i32.const 50
     i64.const 51
     local.get 0
-    br_if 0 (;@0;)
+    br_if 0
     drop
     drop
     i32.const 51
@@ -354,33 +354,33 @@
   )
   (func (;86;) (type $sig-3) (param i32)
     local.get 0
-    br_table 0 (;@0;) 0 (;@0;) 0 (;@0;)
+    br_table 0 0 0
   )
   (func (;87;) (type 23) (param i32) (result i32)
     i32.const 50
     local.get 0
-    br_table 0 (;@0;) 0 (;@0;)
+    br_table 0 0
     i32.const 51
   )
   (func (;88;) (type 25) (param i32) (result f32 i64)
     f32.const 0x1.9p+5 (;=50;)
     i64.const 51
     local.get 0
-    br_table 0 (;@0;) 0 (;@0;)
+    br_table 0 0
     f32.const 0x1.98p+5 (;=51;)
     i64.const 52
   )
   (func (;89;) (type $sig-3) (param i32)
     block ;; label = @1
       local.get 0
-      br_table 0 (;@1;) 1 (;@0;) 0 (;@1;)
+      br_table 0 (;@1;) 1 0 (;@1;)
     end
   )
   (func (;90;) (type 23) (param i32) (result i32)
     block (result i32) ;; label = @1
       i32.const 50
       local.get 0
-      br_table 0 (;@1;) 1 (;@0;) 0 (;@1;)
+      br_table 0 (;@1;) 1 0 (;@1;)
       i32.const 51
     end
     i32.const 2
@@ -391,7 +391,7 @@
       i32.const 50
       i32.const 51
       local.get 0
-      br_table 0 (;@1;) 1 (;@0;) 0 (;@1;)
+      br_table 0 (;@1;) 1 0 (;@1;)
       i32.const 51
       i32.const -3
     end
diff --git a/tests/snapshots/testsuite/proposals/gc/binary.wast/108.print b/tests/snapshots/testsuite/proposals/gc/binary.wast/108.print
index 5b782f46..7d6e8576 100644
--- a/tests/snapshots/testsuite/proposals/gc/binary.wast/108.print
+++ b/tests/snapshots/testsuite/proposals/gc/binary.wast/108.print
@@ -5,7 +5,7 @@
       i32.const 1
       if ;; label = @2
         i32.const 1
-        br_table 2 (;@0;)
+        br_table 2
       end
     end
   )
diff --git a/tests/snapshots/testsuite/proposals/gc/br_on_cast.wast/30.print b/tests/snapshots/testsuite/proposals/gc/br_on_cast.wast/30.print
index 3a734546..a7785937 100644
--- a/tests/snapshots/testsuite/proposals/gc/br_on_cast.wast/30.print
+++ b/tests/snapshots/testsuite/proposals/gc/br_on_cast.wast/30.print
@@ -6,21 +6,21 @@
   (func (;0;) (type 1) (param (ref any)) (result (ref $t))
     block (result (ref any)) ;; label = @1
       local.get 0
-      br_on_cast 1 (;@0;) (ref any) (ref $t)
+      br_on_cast 1 (ref any) (ref $t)
     end
     unreachable
   )
   (func (;1;) (type 2) (param anyref) (result (ref $t))
     block (result anyref) ;; label = @1
       local.get 0
-      br_on_cast 1 (;@0;) anyref (ref $t)
+      br_on_cast 1 anyref (ref $t)
     end
     unreachable
   )
   (func (;2;) (type 3) (param anyref) (result (ref null $t))
     block (result anyref) ;; label = @1
       local.get 0
-      br_on_cast 1 (;@0;) anyref (ref null $t)
+      br_on_cast 1 anyref (ref null $t)
     end
     unreachable
   )
diff --git a/tests/snapshots/testsuite/proposals/gc/br_on_cast_fail.wast/30.print b/tests/snapshots/testsuite/proposals/gc/br_on_cast_fail.wast/30.print
index 37468397..a2f3ab6f 100644
--- a/tests/snapshots/testsuite/proposals/gc/br_on_cast_fail.wast/30.print
+++ b/tests/snapshots/testsuite/proposals/gc/br_on_cast_fail.wast/30.print
@@ -5,19 +5,19 @@
   (func (;0;) (type 1) (param (ref any)) (result (ref any))
     block (result (ref $t)) ;; label = @1
       local.get 0
-      br_on_cast_fail 1 (;@0;) (ref any) (ref $t)
+      br_on_cast_fail 1 (ref any) (ref $t)
     end
   )
   (func (;1;) (type 2) (param anyref) (result anyref)
     block (result (ref $t)) ;; label = @1
       local.get 0
-      br_on_cast_fail 1 (;@0;) anyref (ref $t)
+      br_on_cast_fail 1 anyref (ref $t)
     end
   )
   (func (;2;) (type 2) (param anyref) (result anyref)
     block (result (ref null $t)) ;; label = @1
       local.get 0
-      br_on_cast_fail 1 (;@0;) anyref (ref null $t)
+      br_on_cast_fail 1 anyref (ref null $t)
     end
   )
 )
diff --git a/tests/snapshots/testsuite/proposals/gc/br_on_null.wast/5.print b/tests/snapshots/testsuite/proposals/gc/br_on_null.wast/5.print
index 1946ceac..a2f77bfe 100644
--- a/tests/snapshots/testsuite/proposals/gc/br_on_null.wast/5.print
+++ b/tests/snapshots/testsuite/proposals/gc/br_on_null.wast/5.print
@@ -5,17 +5,17 @@
   (type (;3;) (func (param externref)))
   (func (;0;) (type 1) (param $r (ref null $t))
     local.get $r
-    br_on_null 0 (;@0;)
+    br_on_null 0
     drop
   )
   (func (;1;) (type 2) (param $r funcref)
     local.get $r
-    br_on_null 0 (;@0;)
+    br_on_null 0
     drop
   )
   (func (;2;) (type 3) (param $r externref)
     local.get $r
-    br_on_null 0 (;@0;)
+    br_on_null 0
     drop
   )
 )
diff --git a/tests/snapshots/testsuite/proposals/gc/br_table.wast/0.print b/tests/snapshots/testsuite/proposals/gc/br_table.wast/0.print
index c3603f18..69ccd9ac 100644
--- a/tests/snapshots/testsuite/proposals/gc/br_table.wast/0.print
+++ b/tests/snapshots/testsuite/proposals/gc/br_table.wast/0.print
@@ -236,7 +236,7 @@
     loop (result i32) ;; label = @1
       i32.const 3
       i32.const 0
-      br_table 1 (;@0;) 1 (;@0;)
+      br_table 1 1
       i32.const 1
     end
   )
@@ -245,7 +245,7 @@
       call $dummy
       i32.const 4
       i32.const -1
-      br_table 1 (;@0;) 1 (;@0;) 1 (;@0;)
+      br_table 1 1 1
       i32.const 2
     end
   )
@@ -255,7 +255,7 @@
       call $dummy
       i32.const 5
       i32.const 1
-      br_table 1 (;@0;) 1 (;@0;) 1 (;@0;)
+      br_table 1 1 1
     end
   )
   (func (;23;) (type 2) (result i32)
diff --git a/tests/snapshots/testsuite/proposals/gc/func.wast/0.print b/tests/snapshots/testsuite/proposals/gc/func.wast/0.print
index 36cd194c..87259d3a 100644
--- a/tests/snapshots/testsuite/proposals/gc/func.wast/0.print
+++ b/tests/snapshots/testsuite/proposals/gc/func.wast/0.print
@@ -287,41 +287,41 @@
     return
   )
   (func (;74;) (type $sig)
-    br 0 (;@0;)
+    br 0
   )
   (func (;75;) (type $sig-2) (result i32)
     i32.const 79
-    br 0 (;@0;)
+    br 0
   )
   (func (;76;) (type 13) (result i64)
     i64.const 7979
-    br 0 (;@0;)
+    br 0
   )
   (func (;77;) (type 14) (result f32)
     f32.const 0x1.3f999ap+6 (;=79.9;)
-    br 0 (;@0;)
+    br 0
   )
   (func (;78;) (type 15) (result f64)
     f64.const 0x1.3f28f5c28f5c3p+6 (;=79.79;)
-    br 0 (;@0;)
+    br 0
   )
   (func (;79;) (type 10) (result i32 f64)
     i32.const 79
     f64.const 0x1.3f28f5c28f5c3p+6 (;=79.79;)
-    br 0 (;@0;)
+    br 0
   )
   (func (;80;) (type 21) (result i32 i32 i32)
     i32.const 1
     i32.const 2
     i32.const 3
-    br 0 (;@0;)
+    br 0
   )
   (func (;81;) (type $sig-2) (result i32)
     block (result i32) ;; label = @1
       call $dummy
       i32.const 77
     end
-    br 0 (;@0;)
+    br 0
   )
   (func (;82;) (type 22) (result i32 i64)
     block (type 22) (result i32 i64) ;; label = @1
@@ -329,16 +329,16 @@
       i32.const 1
       i64.const 2
     end
-    br 0 (;@0;)
+    br 0
   )
   (func (;83;) (type $sig-3) (param i32)
     local.get 0
-    br_if 0 (;@0;)
+    br_if 0
   )
   (func (;84;) (type 23) (param i32) (result i32)
     i32.const 50
     local.get 0
-    br_if 0 (;@0;)
+    br_if 0
     drop
     i32.const 51
   )
@@ -346,7 +346,7 @@
     i32.const 50
     i64.const 51
     local.get 0
-    br_if 0 (;@0;)
+    br_if 0
     drop
     drop
     i32.const 51
@@ -354,33 +354,33 @@
   )
   (func (;86;) (type $sig-3) (param i32)
     local.get 0
-    br_table 0 (;@0;) 0 (;@0;) 0 (;@0;)
+    br_table 0 0 0
   )
   (func (;87;) (type 23) (param i32) (result i32)
     i32.const 50
     local.get 0
-    br_table 0 (;@0;) 0 (;@0;)
+    br_table 0 0
     i32.const 51
   )
   (func (;88;) (type 25) (param i32) (result f32 i64)
     f32.const 0x1.9p+5 (;=50;)
     i64.const 51
     local.get 0
-    br_table 0 (;@0;) 0 (;@0;)
+    br_table 0 0
     f32.const 0x1.98p+5 (;=51;)
     i64.const 52
   )
   (func (;89;) (type $sig-3) (param i32)
     block ;; label = @1
       local.get 0
-      br_table 0 (;@1;) 1 (;@0;) 0 (;@1;)
+      br_table 0 (;@1;) 1 0 (;@1;)
     end
   )
   (func (;90;) (type 23) (param i32) (result i32)
     block (result i32) ;; label = @1
       i32.const 50
       local.get 0
-      br_table 0 (;@1;) 1 (;@0;) 0 (;@1;)
+      br_table 0 (;@1;) 1 0 (;@1;)
       i32.const 51
     end
     i32.const 2
@@ -391,7 +391,7 @@
       i32.const 50
       i32.const 51
       local.get 0
-      br_table 0 (;@1;) 1 (;@0;) 0 (;@1;)
+      br_table 0 (;@1;) 1 0 (;@1;)
       i32.const 51
       i32.const -3
     end
diff --git a/tests/snapshots/testsuite/proposals/gc/type-equivalence.wast/10.print b/tests/snapshots/testsuite/proposals/gc/type-equivalence.wast/10.print
index ad3b9097..1c5b7713 100644
--- a/tests/snapshots/testsuite/proposals/gc/type-equivalence.wast/10.print
+++ b/tests/snapshots/testsuite/proposals/gc/type-equivalence.wast/10.print
@@ -45,7 +45,7 @@
       i32.const 1
       call_indirect (type $t2)
     end
-    br 0 (;@0;)
+    br 0
   )
   (table (;0;) 2 2 funcref)
   (export "run" (func 2))
diff --git a/tests/snapshots/testsuite/proposals/gc/type-subtyping.wast/17.print b/tests/snapshots/testsuite/proposals/gc/type-subtyping.wast/17.print
index 269bc81a..98ebf663 100644
--- a/tests/snapshots/testsuite/proposals/gc/type-subtyping.wast/17.print
+++ b/tests/snapshots/testsuite/proposals/gc/type-subtyping.wast/17.print
@@ -71,46 +71,46 @@
       table.get 0
       ref.cast (ref $t2)
     end
-    br 0 (;@0;)
+    br 0
   )
   (func (;4;) (type 3)
     block (result (ref null $t1)) ;; label = @1
       i32.const 0
       call_indirect (type $t1)
     end
-    br 0 (;@0;)
+    br 0
   )
   (func (;5;) (type 3)
     block (result (ref null $t1)) ;; label = @1
       i32.const 0
       call_indirect (type $t2)
     end
-    br 0 (;@0;)
+    br 0
   )
   (func (;6;) (type 3)
     block (result (ref null $t1)) ;; label = @1
       i32.const 1
       call_indirect (type $t2)
     end
-    br 0 (;@0;)
+    br 0
   )
   (func (;7;) (type 3)
     i32.const 0
     table.get 0
     ref.cast (ref $t1)
-    br 0 (;@0;)
+    br 0
   )
   (func (;8;) (type 3)
     i32.const 0
     table.get 0
     ref.cast (ref $t2)
-    br 0 (;@0;)
+    br 0
   )
   (func (;9;) (type 3)
     i32.const 1
     table.get 0
     ref.cast (ref $t2)
-    br 0 (;@0;)
+    br 0
   )
   (table (;0;) 3 3 funcref)
   (export "run" (func 3))
diff --git a/tests/snapshots/testsuite/proposals/memory64/binary.wast/173.print b/tests/snapshots/testsuite/proposals/memory64/binary.wast/173.print
index 5b782f46..7d6e8576 100644
--- a/tests/snapshots/testsuite/proposals/memory64/binary.wast/173.print
+++ b/tests/snapshots/testsuite/proposals/memory64/binary.wast/173.print
@@ -5,7 +5,7 @@
       i32.const 1
       if ;; label = @2
         i32.const 1
-        br_table 2 (;@0;)
+        br_table 2
       end
     end
   )
diff --git a/tests/snapshots/testsuite/proposals/multi-memory/binary.wast/98.print b/tests/snapshots/testsuite/proposals/multi-memory/binary.wast/98.print
index 5b782f46..7d6e8576 100644
--- a/tests/snapshots/testsuite/proposals/multi-memory/binary.wast/98.print
+++ b/tests/snapshots/testsuite/proposals/multi-memory/binary.wast/98.print
@@ -5,7 +5,7 @@
       i32.const 1
       if ;; label = @2
         i32.const 1
-        br_table 2 (;@0;)
+        br_table 2
       end
     end
   )
diff --git a/tests/snapshots/testsuite/proposals/multi-memory/store.wast/20.print b/tests/snapshots/testsuite/proposals/multi-memory/store.wast/20.print
index abd99fa9..bbd28320 100644
--- a/tests/snapshots/testsuite/proposals/multi-memory/store.wast/20.print
+++ b/tests/snapshots/testsuite/proposals/multi-memory/store.wast/20.print
@@ -18,7 +18,7 @@
       local.get $i
       i32.const 23
       i32.eq
-      br_if 1 (;@0;)
+      br_if 1
       local.get $i
       local.get $i
       i32.load8_u
@@ -38,7 +38,7 @@
       local.get $i
       i32.const 54
       i32.eq
-      br_if 1 (;@0;)
+      br_if 1
       local.get $i
       local.get $i
       i32.load8_u $mem2
diff --git a/tests/snapshots/testsuite/token.wast/16.print b/tests/snapshots/testsuite/token.wast/16.print
index 5aa5b9fb..a88d7577 100644
--- a/tests/snapshots/testsuite/token.wast/16.print
+++ b/tests/snapshots/testsuite/token.wast/16.print
@@ -1,6 +1,6 @@
 (module
   (type (;0;) (func))
   (func (;0;) (type 0)
-    br 0 (;@0;)
+    br 0
   )
 )
diff --git a/tests/snapshots/testsuite/token.wast/7.print b/tests/snapshots/testsuite/token.wast/7.print
index 4e888b6e..e2a50d7c 100644
--- a/tests/snapshots/testsuite/token.wast/7.print
+++ b/tests/snapshots/testsuite/token.wast/7.print
@@ -1,7 +1,7 @@
 (module
   (type (;0;) (func))
   (func (;0;) (type 0)
-    br 0 (;@0;)
+    br 0
     nop
   )
 )
diff --git a/tests/snapshots/testsuite/unwind.wast/0.print b/tests/snapshots/testsuite/unwind.wast/0.print
index 91966188..39d72248 100644
--- a/tests/snapshots/testsuite/unwind.wast/0.print
+++ b/tests/snapshots/testsuite/unwind.wast/0.print
@@ -9,19 +9,19 @@
   (func (;1;) (type 0)
     i32.const 3
     i64.const 1
-    br 0 (;@0;)
+    br 0
   )
   (func (;2;) (type 1) (result i32)
     i32.const 3
     i64.const 1
     i32.const 9
-    br 0 (;@0;)
+    br 0
   )
   (func (;3;) (type 0)
     i32.const 3
     i64.const 1
     i32.const 1
-    br_if 0 (;@0;)
+    br_if 0
     drop
     drop
   )
@@ -30,7 +30,7 @@
     i64.const 1
     i32.const 9
     i32.const 1
-    br_if 0 (;@0;)
+    br_if 0
     drop
     drop
   )
@@ -38,14 +38,14 @@
     i32.const 3
     i64.const 1
     i32.const 0
-    br_table 0 (;@0;)
+    br_table 0
   )
   (func (;6;) (type 1) (result i32)
     i32.const 3
     i64.const 1
     i32.const 9
     i32.const 0
-    br_table 0 (;@0;)
+    br_table 0
   )
   (func (;7;) (type 1) (result i32)
     i32.const 3