mirror of
https://github.com/hanzoai/wasm2go.git
synced 2026-10-30 15:06:48 +00:00
* wasm2go: a WebAssembly-to-Go ahead-of-time transpiler wasm2go translates a WebAssembly binary into standalone Go source. The generated package runs the module natively — no interpreter and no embedded wasm runtime — so it builds and links like ordinary Go code. This makes it practical to ship a wasm-compiled library (for example a large C/C++ codebase built with the WASI SDK) inside a Go program without the startup and memory cost of a wasm engine. Components: - internal/wasm — the WebAssembly binary parser. - internal/codegen — translates a parsed module into Go source through the SSA lowering + optimization + emission pipeline. - internal/ssa — a lightweight SSA IR plus optimization passes (const-propagation, DCE, CSE, branch folding, memory promotion). - transpile — the public library API: Parse, Translate, and the Transpile one-shot convenience wrapper. - cmd/wasm2go — the command-line interface. - internal/testfixture — shared helper that compiles testdata/*.wat to wasm on demand via wat2wasm. Library API (Options): - Required: Package, OutputImportPath. - Optional: BulkExportPrefix (per-export Inv_<svc>_<mt> dispatch for modules with uniformly-named exports), EntryExports (narrow DCE root set), KeepDeadFuncs (disable DCE for diff/debug), PromotionReportPath (write SSA memory-promotion JSON). Everything else is auto-derived from the input: the SSA pipeline runs unconditionally; data segments emit as //go:embed sidecars; wasi imports translate to Go-native syscalls; modules whose total function-body bytes exceed an internal threshold are emitted as a chain of //go:linkname-split sub-packages so the Go compiler stays inside a bounded per-package memory budget. WASI runtime: full wasi_snapshot_preview1 coverage. Args/environ, clocks, fd_*, path_* (open/create_directory/unlink_file/ remove_directory/rename/filestat_get/filestat_set_times/link/ symlink/readlink), readdir, pread/pwrite, sync/datasync, poll_oneoff (clock + fd-event branches), sched_yield, random_get, proc_exit, proc_raise, sock_accept/recv/send/shutdown — every call routes to the Go stdlib or golang.org/x/sys/unix equivalent. Per-platform companion files (unix/linux/darwin/windows) carry the bits that differ across OSes; the translated module is a normal Go program with the host's ordinary filesystem and network reach. Release engineering for the public repository: - GitHub Actions CI: build, vet, race-enabled tests behind an 85% coverage gate, golangci-lint — all driven through make targets. - Release workflow runs GoReleaser on version tags, including deb/rpm/apk packages, with build-provenance attestations recorded for every release asset. - A release-test workflow runs `make release/check` (GoReleaser config validation + a publish-free dry-run build) on every PR and main push so a broken release is caught before tag time. - golangci-lint and goreleaser are pinned in tools/go.mod and run via `go tool`, so local and CI invocations use the same versions. - `make install/wat2wasm` provisions the wat2wasm CLI the test suite needs, dispatching to the host's package manager (Homebrew on macOS, apt/dnf/pacman/apk on Linux). - Makefile targets for local development. Test coverage is 85.2% of statements overall. * README: document the WASI runtime, performance, and library entry points - Add a "WASI support" subsection explaining the single-file, stdlib-only `wasi_snapshot_preview1` implementation and the resulting cross-platform reach. - Add a "Performance" section with the wazero-vs-wasm2go corpus numbers (cold start 8.4×, short queries up to 81×, TPC-H scans within ±10%). Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]> * ci: align release-test with release.yml — use stable Go The release-test workflow exercises the same `make release/check` dry-run that the publish job runs at tag time, so it should pull the same toolchain. Switch it from `go-version-file: tools/go.mod` to `go-version: stable` to match release.yml. Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]> --------- Co-authored-by: Claude Opus 4.7 (1M context) <[email protected]>
125 lines
12 KiB
WebAssembly Text Format
125 lines
12 KiB
WebAssembly Text Format
;; cg_allops.wat - exhaustive coverage of the legacy fncompiler
|
|
;; numeric / conversion opcode dispatch. One export per opcode family.
|
|
(module
|
|
(func (export "i32_add") (param i32) (param i32) (result i32) (i32.add (local.get 0) (local.get 1)))
|
|
(func (export "i32_sub") (param i32) (param i32) (result i32) (i32.sub (local.get 0) (local.get 1)))
|
|
(func (export "i32_mul") (param i32) (param i32) (result i32) (i32.mul (local.get 0) (local.get 1)))
|
|
(func (export "i32_and") (param i32) (param i32) (result i32) (i32.and (local.get 0) (local.get 1)))
|
|
(func (export "i32_or") (param i32) (param i32) (result i32) (i32.or (local.get 0) (local.get 1)))
|
|
(func (export "i32_xor") (param i32) (param i32) (result i32) (i32.xor (local.get 0) (local.get 1)))
|
|
(func (export "i32_div_s") (param i32) (param i32) (result i32) (i32.div_s (local.get 0) (local.get 1)))
|
|
(func (export "i32_div_u") (param i32) (param i32) (result i32) (i32.div_u (local.get 0) (local.get 1)))
|
|
(func (export "i32_rem_s") (param i32) (param i32) (result i32) (i32.rem_s (local.get 0) (local.get 1)))
|
|
(func (export "i32_rem_u") (param i32) (param i32) (result i32) (i32.rem_u (local.get 0) (local.get 1)))
|
|
(func (export "i32_shl") (param i32) (param i32) (result i32) (i32.shl (local.get 0) (local.get 1)))
|
|
(func (export "i32_shr_s") (param i32) (param i32) (result i32) (i32.shr_s (local.get 0) (local.get 1)))
|
|
(func (export "i32_shr_u") (param i32) (param i32) (result i32) (i32.shr_u (local.get 0) (local.get 1)))
|
|
(func (export "i32_rotl") (param i32) (param i32) (result i32) (i32.rotl (local.get 0) (local.get 1)))
|
|
(func (export "i32_rotr") (param i32) (param i32) (result i32) (i32.rotr (local.get 0) (local.get 1)))
|
|
(func (export "i64_add") (param i64) (param i64) (result i64) (i64.add (local.get 0) (local.get 1)))
|
|
(func (export "i64_sub") (param i64) (param i64) (result i64) (i64.sub (local.get 0) (local.get 1)))
|
|
(func (export "i64_mul") (param i64) (param i64) (result i64) (i64.mul (local.get 0) (local.get 1)))
|
|
(func (export "i64_and") (param i64) (param i64) (result i64) (i64.and (local.get 0) (local.get 1)))
|
|
(func (export "i64_or") (param i64) (param i64) (result i64) (i64.or (local.get 0) (local.get 1)))
|
|
(func (export "i64_xor") (param i64) (param i64) (result i64) (i64.xor (local.get 0) (local.get 1)))
|
|
(func (export "i64_div_s") (param i64) (param i64) (result i64) (i64.div_s (local.get 0) (local.get 1)))
|
|
(func (export "i64_div_u") (param i64) (param i64) (result i64) (i64.div_u (local.get 0) (local.get 1)))
|
|
(func (export "i64_rem_s") (param i64) (param i64) (result i64) (i64.rem_s (local.get 0) (local.get 1)))
|
|
(func (export "i64_rem_u") (param i64) (param i64) (result i64) (i64.rem_u (local.get 0) (local.get 1)))
|
|
(func (export "i64_shl") (param i64) (param i64) (result i64) (i64.shl (local.get 0) (local.get 1)))
|
|
(func (export "i64_shr_s") (param i64) (param i64) (result i64) (i64.shr_s (local.get 0) (local.get 1)))
|
|
(func (export "i64_shr_u") (param i64) (param i64) (result i64) (i64.shr_u (local.get 0) (local.get 1)))
|
|
(func (export "i64_rotl") (param i64) (param i64) (result i64) (i64.rotl (local.get 0) (local.get 1)))
|
|
(func (export "i64_rotr") (param i64) (param i64) (result i64) (i64.rotr (local.get 0) (local.get 1)))
|
|
(func (export "i32c_eq") (param i32) (param i32) (result i32) (i32.eq (local.get 0) (local.get 1)))
|
|
(func (export "i32c_ne") (param i32) (param i32) (result i32) (i32.ne (local.get 0) (local.get 1)))
|
|
(func (export "i32c_lt_s") (param i32) (param i32) (result i32) (i32.lt_s (local.get 0) (local.get 1)))
|
|
(func (export "i32c_lt_u") (param i32) (param i32) (result i32) (i32.lt_u (local.get 0) (local.get 1)))
|
|
(func (export "i32c_gt_s") (param i32) (param i32) (result i32) (i32.gt_s (local.get 0) (local.get 1)))
|
|
(func (export "i32c_gt_u") (param i32) (param i32) (result i32) (i32.gt_u (local.get 0) (local.get 1)))
|
|
(func (export "i32c_le_s") (param i32) (param i32) (result i32) (i32.le_s (local.get 0) (local.get 1)))
|
|
(func (export "i32c_le_u") (param i32) (param i32) (result i32) (i32.le_u (local.get 0) (local.get 1)))
|
|
(func (export "i32c_ge_s") (param i32) (param i32) (result i32) (i32.ge_s (local.get 0) (local.get 1)))
|
|
(func (export "i32c_ge_u") (param i32) (param i32) (result i32) (i32.ge_u (local.get 0) (local.get 1)))
|
|
(func (export "i64c_eq") (param i64) (param i64) (result i32) (i64.eq (local.get 0) (local.get 1)))
|
|
(func (export "i64c_ne") (param i64) (param i64) (result i32) (i64.ne (local.get 0) (local.get 1)))
|
|
(func (export "i64c_lt_s") (param i64) (param i64) (result i32) (i64.lt_s (local.get 0) (local.get 1)))
|
|
(func (export "i64c_lt_u") (param i64) (param i64) (result i32) (i64.lt_u (local.get 0) (local.get 1)))
|
|
(func (export "i64c_gt_s") (param i64) (param i64) (result i32) (i64.gt_s (local.get 0) (local.get 1)))
|
|
(func (export "i64c_gt_u") (param i64) (param i64) (result i32) (i64.gt_u (local.get 0) (local.get 1)))
|
|
(func (export "i64c_le_s") (param i64) (param i64) (result i32) (i64.le_s (local.get 0) (local.get 1)))
|
|
(func (export "i64c_le_u") (param i64) (param i64) (result i32) (i64.le_u (local.get 0) (local.get 1)))
|
|
(func (export "i64c_ge_s") (param i64) (param i64) (result i32) (i64.ge_s (local.get 0) (local.get 1)))
|
|
(func (export "i64c_ge_u") (param i64) (param i64) (result i32) (i64.ge_u (local.get 0) (local.get 1)))
|
|
(func (export "i32_eqz") (param i32) (result i32) (i32.eqz (local.get 0)))
|
|
(func (export "i64_eqz") (param i64) (result i32) (i64.eqz (local.get 0)))
|
|
(func (export "i32u_clz") (param i32) (result i32) (i32.clz (local.get 0)))
|
|
(func (export "i64u_clz") (param i64) (result i64) (i64.clz (local.get 0)))
|
|
(func (export "i32u_ctz") (param i32) (result i32) (i32.ctz (local.get 0)))
|
|
(func (export "i64u_ctz") (param i64) (result i64) (i64.ctz (local.get 0)))
|
|
(func (export "i32u_popcnt") (param i32) (result i32) (i32.popcnt (local.get 0)))
|
|
(func (export "i64u_popcnt") (param i64) (result i64) (i64.popcnt (local.get 0)))
|
|
(func (export "i32_extend8_s") (param i32) (result i32) (i32.extend8_s (local.get 0)))
|
|
(func (export "i32_extend16_s") (param i32) (result i32) (i32.extend16_s (local.get 0)))
|
|
(func (export "i64_extend8_s") (param i64) (result i64) (i64.extend8_s (local.get 0)))
|
|
(func (export "i64_extend16_s") (param i64) (result i64) (i64.extend16_s (local.get 0)))
|
|
(func (export "i64_extend32_s") (param i64) (result i64) (i64.extend32_s (local.get 0)))
|
|
(func (export "f32_add") (param f32) (param f32) (result f32) (f32.add (local.get 0) (local.get 1)))
|
|
(func (export "f64_add") (param f64) (param f64) (result f64) (f64.add (local.get 0) (local.get 1)))
|
|
(func (export "f32_sub") (param f32) (param f32) (result f32) (f32.sub (local.get 0) (local.get 1)))
|
|
(func (export "f64_sub") (param f64) (param f64) (result f64) (f64.sub (local.get 0) (local.get 1)))
|
|
(func (export "f32_mul") (param f32) (param f32) (result f32) (f32.mul (local.get 0) (local.get 1)))
|
|
(func (export "f64_mul") (param f64) (param f64) (result f64) (f64.mul (local.get 0) (local.get 1)))
|
|
(func (export "f32_div") (param f32) (param f32) (result f32) (f32.div (local.get 0) (local.get 1)))
|
|
(func (export "f64_div") (param f64) (param f64) (result f64) (f64.div (local.get 0) (local.get 1)))
|
|
(func (export "f32_min") (param f32) (param f32) (result f32) (f32.min (local.get 0) (local.get 1)))
|
|
(func (export "f64_min") (param f64) (param f64) (result f64) (f64.min (local.get 0) (local.get 1)))
|
|
(func (export "f32_max") (param f32) (param f32) (result f32) (f32.max (local.get 0) (local.get 1)))
|
|
(func (export "f64_max") (param f64) (param f64) (result f64) (f64.max (local.get 0) (local.get 1)))
|
|
(func (export "f32_copysign") (param f32) (param f32) (result f32) (f32.copysign (local.get 0) (local.get 1)))
|
|
(func (export "f64_copysign") (param f64) (param f64) (result f64) (f64.copysign (local.get 0) (local.get 1)))
|
|
(func (export "f32u_abs") (param f32) (result f32) (f32.abs (local.get 0)))
|
|
(func (export "f64u_abs") (param f64) (result f64) (f64.abs (local.get 0)))
|
|
(func (export "f32u_neg") (param f32) (result f32) (f32.neg (local.get 0)))
|
|
(func (export "f64u_neg") (param f64) (result f64) (f64.neg (local.get 0)))
|
|
(func (export "f32u_sqrt") (param f32) (result f32) (f32.sqrt (local.get 0)))
|
|
(func (export "f64u_sqrt") (param f64) (result f64) (f64.sqrt (local.get 0)))
|
|
(func (export "f32u_ceil") (param f32) (result f32) (f32.ceil (local.get 0)))
|
|
(func (export "f64u_ceil") (param f64) (result f64) (f64.ceil (local.get 0)))
|
|
(func (export "f32u_floor") (param f32) (result f32) (f32.floor (local.get 0)))
|
|
(func (export "f64u_floor") (param f64) (result f64) (f64.floor (local.get 0)))
|
|
(func (export "f32u_trunc") (param f32) (result f32) (f32.trunc (local.get 0)))
|
|
(func (export "f64u_trunc") (param f64) (result f64) (f64.trunc (local.get 0)))
|
|
(func (export "f32u_nearest") (param f32) (result f32) (f32.nearest (local.get 0)))
|
|
(func (export "f64u_nearest") (param f64) (result f64) (f64.nearest (local.get 0)))
|
|
(func (export "f32c_eq") (param f32) (param f32) (result i32) (f32.eq (local.get 0) (local.get 1)))
|
|
(func (export "f64c_eq") (param f64) (param f64) (result i32) (f64.eq (local.get 0) (local.get 1)))
|
|
(func (export "f32c_ne") (param f32) (param f32) (result i32) (f32.ne (local.get 0) (local.get 1)))
|
|
(func (export "f64c_ne") (param f64) (param f64) (result i32) (f64.ne (local.get 0) (local.get 1)))
|
|
(func (export "f32c_lt") (param f32) (param f32) (result i32) (f32.lt (local.get 0) (local.get 1)))
|
|
(func (export "f64c_lt") (param f64) (param f64) (result i32) (f64.lt (local.get 0) (local.get 1)))
|
|
(func (export "f32c_gt") (param f32) (param f32) (result i32) (f32.gt (local.get 0) (local.get 1)))
|
|
(func (export "f64c_gt") (param f64) (param f64) (result i32) (f64.gt (local.get 0) (local.get 1)))
|
|
(func (export "f32c_le") (param f32) (param f32) (result i32) (f32.le (local.get 0) (local.get 1)))
|
|
(func (export "f64c_le") (param f64) (param f64) (result i32) (f64.le (local.get 0) (local.get 1)))
|
|
(func (export "f32c_ge") (param f32) (param f32) (result i32) (f32.ge (local.get 0) (local.get 1)))
|
|
(func (export "f64c_ge") (param f64) (param f64) (result i32) (f64.ge (local.get 0) (local.get 1)))
|
|
(func (export "cv_wrap") (param i64) (result i32) (i32.wrap_i64 (local.get 0)))
|
|
(func (export "cv_ext_s") (param i32) (result i64) (i64.extend_i32_s (local.get 0)))
|
|
(func (export "cv_ext_u") (param i32) (result i64) (i64.extend_i32_u (local.get 0)))
|
|
(func (export "cv_promote") (param f32) (result f64) (f64.promote_f32 (local.get 0)))
|
|
(func (export "cv_demote") (param f64) (result f32) (f32.demote_f64 (local.get 0)))
|
|
(func (export "cv_f32_i32_s") (param i32) (result f32) (f32.convert_i32_s (local.get 0)))
|
|
(func (export "cv_f32_i64_s") (param i64) (result f32) (f32.convert_i64_s (local.get 0)))
|
|
(func (export "cv_f64_i32_s") (param i32) (result f64) (f64.convert_i32_s (local.get 0)))
|
|
(func (export "cv_f64_i64_s") (param i64) (result f64) (f64.convert_i64_s (local.get 0)))
|
|
(func (export "cv_f32_i32_u") (param i32) (result f32) (f32.convert_i32_u (local.get 0)))
|
|
(func (export "cv_f32_i64_u") (param i64) (result f32) (f32.convert_i64_u (local.get 0)))
|
|
(func (export "cv_f64_i32_u") (param i32) (result f64) (f64.convert_i32_u (local.get 0)))
|
|
(func (export "cv_f64_i64_u") (param i64) (result f64) (f64.convert_i64_u (local.get 0)))
|
|
(func (export "cv_ri_f32") (param f32) (result i32) (i32.reinterpret_f32 (local.get 0)))
|
|
(func (export "cv_ri_f64") (param f64) (result i64) (i64.reinterpret_f64 (local.get 0)))
|
|
(func (export "cv_ri_i32") (param i32) (result f32) (f32.reinterpret_i32 (local.get 0)))
|
|
(func (export "cv_ri_i64") (param i64) (result f64) (f64.reinterpret_i64 (local.get 0)))
|
|
)
|