Watgo – Go 的 WebAssembly 工具包
Watgo – A WebAssembly Toolkit for Go

原始链接: https://eli.thegreenplace.net/2026/watgo-a-webassembly-toolkit-for-go/

## watgo:Go 的新型 WebAssembly 工具包 watgo 是一个全新的、无依赖的 WebAssembly 工具包,用纯 Go 编写,提供与 wabt 和 wasm-tools 等现有工具类似的功能。它提供了一个命令行界面 (CLI) 和一个 Go API,用于解析、验证、编码和解码 WebAssembly 模块,在 WAT(文本格式)和 WASM(二进制格式)之间进行转换。 其核心是 `wasmır`,这是一个 WebAssembly 模块的语义表示,允许检查和操作。CLI 旨在与 `wasm-tools` 兼容,并且已经在 `wasm-wat-samples` 等项目中被使用。 Go API 实现了 WASM 模块的程序化分析,例如解析一个简单的 WAT 程序并计数指令。watgo 严格测试其正确性,利用官方 WebAssembly 规范测试套件(近 20 万行 WAT 文件)和 wabt 的 interp 测试套件,确保全面覆盖并全部通过测试。 目前,到抽象语法树 (AST) 的 WAT 解析是内部的,但未来可能会根据用户兴趣考虑公开访问。

对不起。
相关文章

原文

I'm happy to announce the general availability of watgo - the WebAssembly Toolkit for Go. This project is similar to wabt (C++) or wasm-tools (Rust), but in pure, zero-dependency Go.

watgo comes with a CLI and a Go API to parse WAT (WebAssembly Text), validate it, and encode it into WASM binaries; it also supports decoding WASM from its binary format.

At the center of it all is wasmir - a semantic representation of a WebAssembly module that users can examine (and manipulate). This diagram shows the functionalities provided by watgo:

Block diagram showing the different parts of watgo; described in the next paragraph
  • Parse: a parser from WAT to wasmir
  • Validate: uses the official WebAssembly validation semantics to check that the module is well formed and safe
  • Encode: emits wasmir into WASM binary representation
  • Decode: read WASM binary representation into wasmir

CLI use case

watgo comes with a CLI, which you can install by issuing this command:

go install github.com/eliben/watgo/cmd/watgo@latest

The CLI aims to be compatible with wasm-tools , and I've already switched my wasm-wat-samples projects to use it; e.g. a command to parse a WAT file, validate it and encode it into binary format:

watgo parse stack.wat -o stack.wasm

API use case

wasmir semantically represents a WASM module with an API that's easy to work with. Here's an example of using watgo to parse a simple WAT program and do some analysis:

package main

import (
  "fmt"

  "github.com/eliben/watgo"
  "github.com/eliben/watgo/wasmir"
)

const wasmText = `
(module
  (func (export "add") (param i32 i32) (result i32)
    local.get 0
    local.get 1
    i32.add
  )
  (func (param f32 i32) (result i32)
    local.get 1
    i32.const 1
    i32.add
    drop
    i32.const 0
  )
)`

func main() {
  m, err := watgo.ParseWAT([]byte(wasmText))
  if err != nil {
    panic(err)
  }

  i32Params := 0
  localGets := 0
  i32Adds := 0

  // Module-defined functions carry a type index into m.Types. The function
  // body itself is a flat sequence of wasmir.Instruction values.
  for _, fn := range m.Funcs {
    sig := m.Types[fn.TypeIdx]
    for _, param := range sig.Params {
      if param.Kind == wasmir.ValueKindI32 {
        i32Params++
      }
    }

    for _, instr := range fn.Body {
      switch instr.Kind {
      case wasmir.InstrLocalGet:
        localGets++
      case wasmir.InstrI32Add:
        i32Adds++
      }
    }
  }

  fmt.Printf("module-defined funcs: %d\n", len(m.Funcs))
  fmt.Printf("i32 params: %d\n", i32Params)
  fmt.Printf("local.get instructions: %d\n", localGets)
  fmt.Printf("i32.add instructions: %d\n", i32Adds)
}

One important note: the WAT format supports several syntactic niceties that are flattened / canonicalized when lowered to wasmir. For example, all folded instructions are lowered to unfolded ones (linear form), function & type names are resolved to numeric indices, etc. This matches the validation and execution semantics of WASM and its binary representation.

These syntactic details are present in watgo in the textformat package (which parses WAT into an AST) and are removed when this is lowered to wasmir. The textformat package is kept internal at this time, but in the future I may consider exposing it publicly - if there's interest.

Testing strategy

Even though it's still early days for watgo, I'm reasonably confident in its correctness due to a strategy of very heavy testing right from the start.

WebAssembly comes with a large official test suite, which is perfect for end-to-end testing of new implementations. The core test suite includes almost 200K lines of WAT files that carry several modules with expected execution semantics and a variety of error scenarios exercised. These live in specially designed .wast files and leverage a custom spec interpreter.

watgo hijacks this approach by using the official test suite for its own testing. A custom harness parses .wast files and uses watgo to convert the WAT in them to binary WASM, which is then executed by Node.js ; this harness is a significant effort in itself, but it's very much worth it - the result is excellent testing coverage. watgo passes the entire WASM spec core test suite.

Similarly, we leverage wabt's interp test suite which also includes end-to-end tests, using a simpler Node-based harness to test them against watgo.

Finally, I maintain a collection of realistic program samples written in WAT in the wasm-wat-samples repository; these are also used by watgo to test itself.


联系我们 contact @ memedata.com