diff --git a/.github/workflows/commit.yaml b/.github/workflows/commit.yaml index 43695ce4..f726e2a5 100644 --- a/.github/workflows/commit.yaml +++ b/.github/workflows/commit.yaml @@ -28,7 +28,7 @@ jobs: matrix: # use latest available versions and be consistent on all workflows! go-version: - "1.17" # == ${{ env.GO_VERSION }} because matrix cannot expand env variables - - "1.18" + - "1.19.0-rc.2" # TODO: use 1.19.0 after the release. steps: - uses: actions/setup-go@v3 @@ -64,7 +64,7 @@ jobs: os: [ubuntu-20.04, macos-12, windows-2022] go-version: - "1.17" # == ${{ env.GO_VERSION }} because matrix cannot expand env variables - - "1.18" + - "1.19.0-rc.2" # TODO: use 1.19.0 after the release. steps: - uses: actions/setup-go@v3 @@ -100,7 +100,7 @@ jobs: matrix: go-version: - "1.17" # == ${{ env.GO_VERSION }} because matrix cannot expand env variables - - "1.18" + - "1.19.0-rc.2" # TODO: use 1.19.0 after the release. steps: - uses: actions/setup-go@v3 @@ -132,7 +132,7 @@ jobs: matrix: go-version: - "1.17" # == ${{ env.GO_VERSION }} because matrix cannot expand env variables - - "1.18" + - "1.19.0-rc.2" # TODO: use 1.19.0 after the release. arch: - "amd64" - "arm64" diff --git a/.github/workflows/spectest.yaml b/.github/workflows/spectest.yaml index c62c4546..878630c5 100644 --- a/.github/workflows/spectest.yaml +++ b/.github/workflows/spectest.yaml @@ -26,7 +26,7 @@ jobs: matrix: go-version: - "1.17" - - "1.18" + - "1.19.0-rc.2" # TODO: use 1.19.0 after the release. spec-version: - "v1" - "v2" @@ -55,7 +55,7 @@ jobs: matrix: go-version: - "1.17" - - "1.18" + - "1.19.0-rc.2" # TODO: use 1.19.0 after the release. spec-version: - "v1" - "v2" @@ -90,7 +90,7 @@ jobs: matrix: go-version: - "1.17" - - "1.18" + - "1.19.0-rc.2" # TODO: use 1.19.0 after the release. arch: - "arm64" - "riscv64" diff --git a/api/wasm.go b/api/wasm.go index 4db74777..695856c4 100644 --- a/api/wasm.go +++ b/api/wasm.go @@ -54,11 +54,11 @@ func ExternTypeName(et ExternType) string { // // The following describes how to convert between Wasm and Golang types: // -// * ValueTypeI32 - uint64(uint32,int32) -// * ValueTypeI64 - uint64(int64) -// * ValueTypeF32 - EncodeF32 DecodeF32 from float32 -// * ValueTypeF64 - EncodeF64 DecodeF64 from float64 -// * ValueTypeExternref - unintptr(unsafe.Pointer(p)) where p is any pointer type in Go (e.g. *string) +// - ValueTypeI32 - uint64(uint32,int32) +// - ValueTypeI64 - uint64(int64) +// - ValueTypeF32 - EncodeF32 DecodeF32 from float32 +// - ValueTypeF64 - EncodeF64 DecodeF64 from float64 +// - ValueTypeExternref - unintptr(unsafe.Pointer(p)) where p is any pointer type in Go (e.g. *string) // // Ex. Given a Text Format type use (param i64) (result i64), no conversion is necessary. // @@ -127,8 +127,8 @@ func ValueTypeName(t ValueType) string { // // Notes // -// * Closing the wazero.Runtime closes any Module it instantiated. -// * This is an interface for decoupling, not third-party implementations. All implementations are in wazero. +// - Closing the wazero.Runtime closes any Module it instantiated. +// - This is an interface for decoupling, not third-party implementations. All implementations are in wazero. // // See https://www.w3.org/TR/2019/REC-wasm-core-1-20191205/#external-types%E2%91%A0 type Module interface { @@ -318,9 +318,9 @@ type MutableGlobal interface { // // Notes // -// * All functions accept a context.Context, which when nil, default to context.Background. -// * This is an interface for decoupling, not third-party implementations. All implementations are in wazero. -// * This includes all value types available in WebAssembly 1.0 (20191205) and all are encoded little-endian. +// - All functions accept a context.Context, which when nil, default to context.Background. +// - This is an interface for decoupling, not third-party implementations. All implementations are in wazero. +// - This includes all value types available in WebAssembly 1.0 (20191205) and all are encoded little-endian. // // See https://www.w3.org/TR/2019/REC-wasm-core-1-20191205/#storage%E2%91%A0 type Memory interface { @@ -489,6 +489,7 @@ func DecodeF64(input uint64) float64 { // This determines the amount of memory pages (65536 bytes per page) to use when a memory is instantiated as a []byte. // // Ex. Here's how to set the capacity to max instead of min, when set: +// // capIsMax := func(minPages uint32, maxPages *uint32) (min, capacity, max uint32) { // if maxPages != nil { // return minPages, *maxPages, *maxPages diff --git a/assemblyscript/assemblyscript.go b/assemblyscript/assemblyscript.go index 1e783346..3cd522af 100644 --- a/assemblyscript/assemblyscript.go +++ b/assemblyscript/assemblyscript.go @@ -1,26 +1,26 @@ // Package assemblyscript contains Go-defined special functions imported by // AssemblyScript under the module name "env". // -// Special Functions +// # Special Functions // // AssemblyScript code import the below special functions when not using WASI. // Note: Sometimes only "abort" is imported. // -// * "abort" - exits with 255 with an abort message written to -// wazero.ModuleConfig WithStderr. -// * "trace" - no output unless. -// * "seed" - uses wazero.ModuleConfig WithRandSource as the source of seed -// values. +// - "abort" - exits with 255 with an abort message written to +// wazero.ModuleConfig WithStderr. +// - "trace" - no output unless. +// - "seed" - uses wazero.ModuleConfig WithRandSource as the source of seed +// values. // -// Relationship to WASI +// # Relationship to WASI // // A program compiled to use WASI, via "import wasi" in any file, won't import // these functions. // // See wasi_snapshot_preview1.Instantiate and -// * https://www.assemblyscript.org/concepts.html#special-imports -// * https://www.assemblyscript.org/concepts.html#targeting-wasi -// * https://www.assemblyscript.org/compiler.html#compiler-options +// - https://www.assemblyscript.org/concepts.html#special-imports +// - https://www.assemblyscript.org/concepts.html#targeting-wasi +// - https://www.assemblyscript.org/compiler.html#compiler-options package assemblyscript import ( @@ -49,9 +49,9 @@ const ( // // Notes // -// * Closing the wazero.Runtime has the same effect as closing the result. -// * To add more functions to the "env" module, use FunctionExporter. -// * To instantiate into another wazero.Namespace, use FunctionExporter. +// - Closing the wazero.Runtime has the same effect as closing the result. +// - To add more functions to the "env" module, use FunctionExporter. +// - To instantiate into another wazero.Namespace, use FunctionExporter. func Instantiate(ctx context.Context, r wazero.Runtime) (api.Closer, error) { builder := r.NewModuleBuilder("env") NewFunctionExporter().ExportFunctions(builder) @@ -121,6 +121,7 @@ func (e *functionExporter) ExportFunctions(builder wazero.ModuleBuilder) { // // Here's the import in a user's module that ends up using this, in WebAssembly // 1.0 (MVP) Text Format: +// // (import "env" "abort" (func $~lib/builtins/abort (param i32 i32 i32 i32))) // // See https://github.com/AssemblyScript/assemblyscript/blob/fa14b3b03bd4607efa52aaff3132bea0c03a7989/std/assembly/wasi/index.ts#L18 @@ -183,10 +184,12 @@ var traceStderr = traceStdout.MustGoFunc(func( }) // traceTo implements the function "trace" in AssemblyScript. Ex. +// // trace('Hello World!') // // Here's the import in a user's module that ends up using this, in WebAssembly // 1.0 (MVP) Text Format: +// // (import "env" "trace" (func $~lib/builtins/trace (param i32 i32 f64 f64 f64 f64 f64))) // // See https://github.com/AssemblyScript/assemblyscript/blob/fa14b3b03bd4607efa52aaff3132bea0c03a7989/std/assembly/wasi/index.ts#L61 @@ -234,6 +237,7 @@ func formatFloat(f float64) string { // // Here's the import in a user's module that ends up using this, in WebAssembly // 1.0 (MVP) Text Format: +// // (import "env" "seed" (func $~lib/builtins/seed (result f64))) // // See https://github.com/AssemblyScript/assemblyscript/blob/fa14b3b03bd4607efa52aaff3132bea0c03a7989/std/assembly/wasi/index.ts#L111 diff --git a/builder.go b/builder.go index e086d7d9..75bf18c2 100644 --- a/builder.go +++ b/builder.go @@ -38,12 +38,12 @@ import ( // // Notes // -// * ModuleBuilder is mutable: each method returns the same instance for -// chaining. -// * methods do not return errors, to allow chaining. Any validation errors -// are deferred until Compile. -// * Insertion order is not retained. Anything defined by this builder is -// sorted lexicographically on Compile. +// - ModuleBuilder is mutable: each method returns the same instance for +// chaining. +// - methods do not return errors, to allow chaining. Any validation errors +// are deferred until Compile. +// - Insertion order is not retained. Anything defined by this builder is +// sorted lexicographically on Compile. type ModuleBuilder interface { // Note: until golang/go#5860, we can't use example tests to embed code in interface godocs. diff --git a/config.go b/config.go index dd90a444..cff4236f 100644 --- a/config.go +++ b/config.go @@ -21,6 +21,7 @@ import ( // RuntimeConfig controls runtime behavior, with the default implementation as NewRuntimeConfig // // Ex. To explicitly limit to Wasm Core 1.0 features as opposed to relying on defaults: +// // rConfig = wazero.NewRuntimeConfig().WithWasmCore1() // // Note: RuntimeConfig is immutable. Each WithXXX function returns a new instance including the corresponding change. @@ -369,6 +370,7 @@ func (c *compileConfig) WithMemorySizer(memorySizer api.MemorySizer) CompileConf // multiple times. // // Ex. +// // // Initialize base configuration: // config := wazero.NewModuleConfig().WithStdout(buf).WithSysNanotime() // diff --git a/emscripten/emscripten.go b/emscripten/emscripten.go index ab8d2781..040b19e5 100644 --- a/emscripten/emscripten.go +++ b/emscripten/emscripten.go @@ -4,7 +4,7 @@ // Emscripten has many imports which are triggered on build flags. Use // FunctionExporter, instead of Instantiate, to define more "env" functions. // -// Relationship to WASI +// # Relationship to WASI // // Emscripten typically requires wasi_snapshot_preview1 to implement exit. // @@ -25,9 +25,9 @@ import ( // // Notes // -// * Closing the wazero.Runtime has the same effect as closing the result. -// * To add more functions to the "env" module, use FunctionExporter. -// * To instantiate into another wazero.Namespace, use FunctionExporter. +// - Closing the wazero.Runtime has the same effect as closing the result. +// - To add more functions to the "env" module, use FunctionExporter. +// - To instantiate into another wazero.Namespace, use FunctionExporter. func Instantiate(ctx context.Context, r wazero.Runtime) (api.Closer, error) { builder := r.NewModuleBuilder("env") NewFunctionExporter().ExportFunctions(builder) @@ -64,6 +64,7 @@ func (e *functionExporter) ExportFunctions(builder wazero.ModuleBuilder) { // // Here's the import in a user's module that ends up using this, in WebAssembly // 1.0 (MVP) Text Format: +// // (import "env" "emscripten_notify_memory_growth" // (func $emscripten_notify_memory_growth (param $memory_index i32))) // diff --git a/emscripten/emscripten_test.go b/emscripten/emscripten_test.go index 4d026298..91de67df 100644 --- a/emscripten/emscripten_test.go +++ b/emscripten/emscripten_test.go @@ -14,6 +14,7 @@ import ( ) // growWasm was compiled from testdata/grow.cc +// //go:embed testdata/grow.wasm var growWasm []byte diff --git a/example_test.go b/example_test.go index 374d22c2..39c01b74 100644 --- a/example_test.go +++ b/example_test.go @@ -8,7 +8,9 @@ import ( ) // addWasm was generated by the following: +// // cd examples/basic/testdata/testdata; wat2wasm --debug-names add.wat +// //go:embed examples/basic/testdata/add.wasm var addWasm []byte diff --git a/examples/allocation/rust/greet.go b/examples/allocation/rust/greet.go index cf68349b..a5ffa748 100644 --- a/examples/allocation/rust/greet.go +++ b/examples/allocation/rust/greet.go @@ -12,6 +12,7 @@ import ( ) // greetWasm was compiled using `cargo build --release --target wasm32-unknown-unknown` +// //go:embed testdata/greet.wasm var greetWasm []byte diff --git a/examples/allocation/tinygo/greet.go b/examples/allocation/tinygo/greet.go index cc2ca1b4..d55fb6e0 100644 --- a/examples/allocation/tinygo/greet.go +++ b/examples/allocation/tinygo/greet.go @@ -13,6 +13,7 @@ import ( ) // greetWasm was compiled using `tinygo build -o greet.wasm -scheduler=none --no-debug -target=wasi greet.go` +// //go:embed testdata/greet.wasm var greetWasm []byte diff --git a/examples/allocation/tinygo/testdata/greet.go b/examples/allocation/tinygo/testdata/greet.go index eb4722d9..d858ab38 100644 --- a/examples/allocation/tinygo/testdata/greet.go +++ b/examples/allocation/tinygo/testdata/greet.go @@ -24,6 +24,7 @@ func log(message string) { // byteCount) to the console. // // Note: In TinyGo "//export" on a func is actually an import! +// //go:wasm-module env //export log func _log(ptr uint32, size uint32) @@ -35,6 +36,7 @@ func greeting(name string) string { // _greet is a WebAssembly export that accepts a string pointer (linear memory // offset) and calls greet. +// //export greet func _greet(ptr, size uint32) { name := ptrToString(ptr, size) @@ -46,6 +48,7 @@ func _greet(ptr, size uint32) { // // Note: This uses a uint64 instead of two result values for compatibility with // WebAssembly 1.0. +// //export greeting func _greeting(ptr, size uint32) (ptrSize uint64) { name := ptrToString(ptr, size) diff --git a/examples/assemblyscript/assemblyscript.go b/examples/assemblyscript/assemblyscript.go index 3114fb51..c754e60c 100644 --- a/examples/assemblyscript/assemblyscript.go +++ b/examples/assemblyscript/assemblyscript.go @@ -13,6 +13,7 @@ import ( ) // asWasm compiled using `npm install && npm run build` +// //go:embed testdata/assemblyscript.wasm var asWasm []byte diff --git a/examples/basic/add.go b/examples/basic/add.go index d60226b5..99025f01 100644 --- a/examples/basic/add.go +++ b/examples/basic/add.go @@ -13,7 +13,9 @@ import ( ) // addWasm was generated by the following: +// // cd testdata; wat2wasm --debug-names add.wat +// //go:embed testdata/add.wasm var addWasm []byte diff --git a/examples/import-go/age-calculator.go b/examples/import-go/age-calculator.go index 9f8535c5..5bc4b96d 100644 --- a/examples/import-go/age-calculator.go +++ b/examples/import-go/age-calculator.go @@ -13,7 +13,9 @@ import ( ) // ageCalculatorWasm was generated by the following: +// // cd testdata; wat2wasm --debug-names age_calculator.wat +// //go:embed testdata/age_calculator.wasm var ageCalculatorWasm []byte diff --git a/examples/multiple-results/multiple-results.go b/examples/multiple-results/multiple-results.go index 0c8c884f..b5ac5d2f 100644 --- a/examples/multiple-results/multiple-results.go +++ b/examples/multiple-results/multiple-results.go @@ -17,15 +17,17 @@ import ( // The portable approach uses parameters to return additional results. The // parameter value is a memory offset to write the next value. This is the same // approach used by WASI. -// * resultOffsetWasmFunctions -// * resultOffsetHostFunctions +// - resultOffsetWasmFunctions +// - resultOffsetHostFunctions +// // See https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md // // Another approach is to enable the "multiple-results" feature. While // "multiple-results" is not yet a W3C recommendation, most WebAssembly // runtimes support it by default, and it is include in the draft of 2.0. -// * multiValueWasmFunctions -// * multiValueHostFunctions +// - multiValueWasmFunctions +// - multiValueHostFunctions +// // See https://github.com/WebAssembly/spec/blob/main/proposals/multi-value/Overview.md func main() { // Choose the context to use for function calls. @@ -112,7 +114,9 @@ func resultOffsetHostFunctions(ctx context.Context, r wazero.Runtime) (api.Modul } // resultOffsetWasm was generated by the following: +// // cd testdata; wat2wasm --debug-names result_offset.wat +// //go:embed testdata/result_offset.wasm var resultOffsetWasm []byte @@ -140,7 +144,9 @@ func multiValueHostFunctions(ctx context.Context, r wazero.Runtime) (api.Module, } // multiValueWasm was generated by the following: +// // cd testdata; wat2wasm --debug-names multi_value.wat +// //go:embed testdata/multi_value.wasm var multiValueWasm []byte diff --git a/examples/namespace/counter.go b/examples/namespace/counter.go index 69626150..9ac8320e 100644 --- a/examples/namespace/counter.go +++ b/examples/namespace/counter.go @@ -11,7 +11,9 @@ import ( ) // counterWasm was generated by the following: +// // cd testdata; wat2wasm --debug-names counter.wat +// //go:embed testdata/counter.wasm var counterWasm []byte diff --git a/examples/wasi/cat.go b/examples/wasi/cat.go index fddca6d2..2da57ccb 100644 --- a/examples/wasi/cat.go +++ b/examples/wasi/cat.go @@ -15,18 +15,22 @@ import ( ) // catFS is an embedded filesystem limited to test.txt +// //go:embed testdata/test.txt var catFS embed.FS // catWasmCargoWasi was compiled from testdata/cargo-wasi/cat.rs +// //go:embed testdata/cargo-wasi/cat.wasm var catWasmCargoWasi []byte // catWasmTinyGo was compiled from testdata/tinygo/cat.go +// //go:embed testdata/tinygo/cat.wasm var catWasmTinyGo []byte // catWasmZigCc was compiled from testdata/zig-cc/cat.c +// //go:embed testdata/zig-cc/cat.wasm var catWasmZigCc []byte diff --git a/experimental/fs_example_test.go b/experimental/fs_example_test.go index 608d024c..716a8eac 100644 --- a/experimental/fs_example_test.go +++ b/experimental/fs_example_test.go @@ -13,7 +13,9 @@ import ( ) // fsWasm was generated by the following: +// // cd testdata; wat2wasm --debug-names fs.wat +// //go:embed testdata/fs.wasm var fsWasm []byte diff --git a/experimental/log_listener_example_test.go b/experimental/log_listener_example_test.go index 9a848418..c7d0f78d 100644 --- a/experimental/log_listener_example_test.go +++ b/experimental/log_listener_example_test.go @@ -12,7 +12,9 @@ import ( ) // listenerWasm was generated by the following: +// // cd testdata; wat2wasm --debug-names listener.wat +// //go:embed testdata/listener.wasm var listenerWasm []byte diff --git a/internal/engine/compiler/engine.go b/internal/engine/compiler/engine.go index f958512b..54fe3f0f 100644 --- a/internal/engine/compiler/engine.go +++ b/internal/engine/compiler/engine.go @@ -632,10 +632,10 @@ func newEngine(enabledFeatures wasm.Features) *engine { // // On Go upgrades, re-validate heap-allocation via `go build -gcflags='-m' ./internal/engine/compiler/...`. // -// [1] https://github.com/golang/go/blob/68ecdc2c70544c303aa923139a5f16caf107d955/src/cmd/compile/internal/escape/utils.go#L206-L208 -// [2] https://github.com/golang/go/blob/68ecdc2c70544c303aa923139a5f16caf107d955/src/runtime/mgc.go#L9 -// [3] https://mayurwadekar2.medium.com/escape-analysis-in-golang-ee40a1c064c1 -// [4] https://medium.com/@yulang.chu/go-stack-or-heap-2-slices-which-keep-in-stack-have-limitation-of-size-b3f3adfd6190 +// [1] https://github.com/golang/go/blob/68ecdc2c70544c303aa923139a5f16caf107d955/src/cmd/compile/internal/escape/utils.go#L206-L208 +// [2] https://github.com/golang/go/blob/68ecdc2c70544c303aa923139a5f16caf107d955/src/runtime/mgc.go#L9 +// [3] https://mayurwadekar2.medium.com/escape-analysis-in-golang-ee40a1c064c1 +// [4] https://medium.com/@yulang.chu/go-stack-or-heap-2-slices-which-keep-in-stack-have-limitation-of-size-b3f3adfd6190 var ( initialValueStackSize = 64 initialCallFrameStackSize = 16 diff --git a/internal/engine/compiler/impl_amd64.go b/internal/engine/compiler/impl_amd64.go index ca825cb5..4ff33eaa 100644 --- a/internal/engine/compiler/impl_amd64.go +++ b/internal/engine/compiler/impl_amd64.go @@ -1071,9 +1071,10 @@ func (c *amd64Compiler) compileMul(o *wazeroir.OperationMul) (err error) { // Here, we mean "the overflow info" by 65 bit or higher part of the result for 64 bit case. // // So, we have to ensure that -// 1) Previously located value on DX must be saved to memory stack. That is because -// the existing value will be overridden after the mul execution. -// 2) One of the operands (x1 or x2) must be on AX register. +// 1. Previously located value on DX must be saved to memory stack. That is because +// the existing value will be overridden after the mul execution. +// 2. One of the operands (x1 or x2) must be on AX register. +// // See https://www.felixcloutier.com/x86/mul#description for detail semantics. func (c *amd64Compiler) compileMulForInts(is32Bit bool, mulInstruction asm.Instruction) error { const ( @@ -2007,7 +2008,9 @@ func (c *amd64Compiler) compileI32WrapFromI64() error { // According to the Intel manual ([1],[2]), if the source float value is either +-Inf or NaN, or it exceeds representative ranges // of target signed integer, then the instruction returns "masked" response float32SignBitMask (or float64SignBitMask for 64 bit case). // [1] Chapter 11.5.2, SIMD Floating-Point Exception Conditions in "Vol 1, Intel® 64 and IA-32 Architectures Manual" -// https://www.intel.com/content/www/us/en/architecture-and-technology/64-ia-32-architectures-software-developer-vol-1-manual.html +// +// https://www.intel.com/content/www/us/en/architecture-and-technology/64-ia-32-architectures-software-developer-vol-1-manual.html +// // [2] https://xem.github.io/minix86/manual/intel-x86-and-64-manual-vol1/o_7281d5ea06a5b67a-268.html func (c *amd64Compiler) compileITruncFromF(o *wazeroir.OperationITruncFromF) (err error) { if o.InputType == wazeroir.Float32 && o.OutputType == wazeroir.SignedInt32 { diff --git a/internal/engine/compiler/impl_arm64.go b/internal/engine/compiler/impl_arm64.go index 8ffa1c9c..4c82d686 100644 --- a/internal/engine/compiler/impl_arm64.go +++ b/internal/engine/compiler/impl_arm64.go @@ -1,7 +1,6 @@ // This file implements the compiler for arm64 target. // Please refer to https://developer.arm.com/documentation/102374/latest/ // if unfamiliar with arm64 instructions and semantics. -// package compiler import ( diff --git a/internal/integration_test/bench/bench_test.go b/internal/integration_test/bench/bench_test.go index 3cd13047..7db14e27 100644 --- a/internal/integration_test/bench/bench_test.go +++ b/internal/integration_test/bench/bench_test.go @@ -17,6 +17,7 @@ import ( var testCtx = context.WithValue(context.Background(), struct{}{}, "arbitrary") // caseWasm was compiled from TinyGo testdata/case.go +// //go:embed testdata/case.wasm var caseWasm []byte diff --git a/internal/integration_test/fs/fs_test.go b/internal/integration_test/fs/fs_test.go index 4d511956..8fab1a96 100644 --- a/internal/integration_test/fs/fs_test.go +++ b/internal/integration_test/fs/fs_test.go @@ -22,7 +22,9 @@ var testCtx = context.Background() var animals []byte // fsWasm was generated by the following: +// // cd testdata; wat2wasm --debug-names fs.wat +// //go:embed testdata/fs.wasm var fsWasm []byte diff --git a/internal/integration_test/spectest/spectest.go b/internal/integration_test/spectest/spectest.go index 7efbf95f..2b16c2c0 100644 --- a/internal/integration_test/spectest/spectest.go +++ b/internal/integration_test/spectest/spectest.go @@ -661,10 +661,10 @@ func testdataPath(filename string) string { } // valuesEq returns true if all the actual result matches exps which are all expressed as uint64. -// * actual,exps: comparison target values which are all represented as uint64, meaning that if valTypes = [V128,I32], then -// we have actual/exp = [(lower-64bit of the first V128), (higher-64bit of the first V128), I32]. -// * valTypes holds the wasm.ValueType(s) of the original values in Wasm. -// * laneTypes maps the index of valueTypes to laneType if valueTypes[i] == wasm.ValueTypeV128. +// - actual,exps: comparison target values which are all represented as uint64, meaning that if valTypes = [V128,I32], then +// we have actual/exp = [(lower-64bit of the first V128), (higher-64bit of the first V128), I32]. +// - valTypes holds the wasm.ValueType(s) of the original values in Wasm. +// - laneTypes maps the index of valueTypes to laneType if valueTypes[i] == wasm.ValueTypeV128. // // Also, if matched == false this returns non-empty valuesMsg which can be used to augment the test failure message. func valuesEq(actual, exps []uint64, valTypes []wasm.ValueType, laneTypes map[int]laneType) (matched bool, valuesMsg string) { diff --git a/internal/integration_test/vs/bench.go b/internal/integration_test/vs/bench.go index fbc662db..f1124a2b 100644 --- a/internal/integration_test/vs/bench.go +++ b/internal/integration_test/vs/bench.go @@ -17,6 +17,7 @@ import ( var testCtx = context.WithValue(context.Background(), struct{}{}, "arbitrary") // ensureCompilerFastest is overridable via ldflags. Ex. +// // -ldflags '-X github.com/tetratelabs/wazero/internal/integration_test/vs.ensureCompilerFastest=true' var ensureCompilerFastest = "false" diff --git a/internal/platform/time_cgo.go b/internal/platform/time_cgo.go index 6857f490..0b3338d1 100644 --- a/internal/platform/time_cgo.go +++ b/internal/platform/time_cgo.go @@ -6,6 +6,7 @@ import _ "unsafe" // for go:linkname // nanotime uses runtime.nanotime as it is available on all platforms and // benchmarks faster than using time.Since. +// //go:noescape //go:linkname nanotime runtime.nanotime func nanotime() int64 diff --git a/internal/testing/enginetest/enginetest.go b/internal/testing/enginetest/enginetest.go index 073159d0..85e90d91 100644 --- a/internal/testing/enginetest/enginetest.go +++ b/internal/testing/enginetest/enginetest.go @@ -2,11 +2,13 @@ // functions is less burden than copy/pasting the implementations, while still allowing test caching to operate. // // Ex. In simplest case, dispatch: +// // func TestModuleEngine_Call(t *testing.T) { // enginetest.RunTestModuleEngine_Call(t, NewEngine) // } // // Ex. Some tests using the Compiler Engine may need to guard as they use compiled features: +// // func TestModuleEngine_Call(t *testing.T) { // requireSupportedOSArch(t) // enginetest.RunTestModuleEngine_Call(t, NewEngine) diff --git a/internal/testing/hammer/hammer.go b/internal/testing/hammer/hammer.go index b5c08fbe..851b2539 100644 --- a/internal/testing/hammer/hammer.go +++ b/internal/testing/hammer/hammer.go @@ -10,6 +10,7 @@ import ( // Hammer invokes a test concurrently in P goroutines N times per goroutine. // // Ex. +// // P := 8 // max count of goroutines // N := 1000 // work per goroutine // if testing.Short() { // Adjust down if `-test.short` diff --git a/internal/testing/require/require.go b/internal/testing/require/require.go index 0780d233..06ecce22 100644 --- a/internal/testing/require/require.go +++ b/internal/testing/require/require.go @@ -26,7 +26,7 @@ type TestingT interface { // Contains fails if `s` does not contain `substr` using strings.Contains. // -// * formatWithArgs are optional. When the first is a string that contains '%', it is treated like fmt.Sprintf. +// - formatWithArgs are optional. When the first is a string that contains '%', it is treated like fmt.Sprintf. func Contains(t TestingT, s, substr string, formatWithArgs ...interface{}) { if !strings.Contains(s, substr) { fail(t, fmt.Sprintf("expected %q to contain %q", s, substr), "", formatWithArgs...) @@ -35,7 +35,7 @@ func Contains(t TestingT, s, substr string, formatWithArgs ...interface{}) { // Equal fails if the actual value is not equal to the expected. // -// * formatWithArgs are optional. When the first is a string that contains '%', it is treated like fmt.Sprintf. +// - formatWithArgs are optional. When the first is a string that contains '%', it is treated like fmt.Sprintf. func Equal(t TestingT, expected, actual interface{}, formatWithArgs ...interface{}) { if equal(expected, actual) { return @@ -88,7 +88,7 @@ func equal(expected, actual interface{}) bool { // EqualError fails if the err is nil or its `Error()` value is not equal to the expected. // -// * formatWithArgs are optional. When the first is a string that contains '%', it is treated like fmt.Sprintf. +// - formatWithArgs are optional. When the first is a string that contains '%', it is treated like fmt.Sprintf. func EqualError(t TestingT, err error, expected string, formatWithArgs ...interface{}) { if err == nil { fail(t, "expected an error, but was nil", "", formatWithArgs...) @@ -102,7 +102,7 @@ func EqualError(t TestingT, err error, expected string, formatWithArgs ...interf // Error fails if the err is nil. // -// * formatWithArgs are optional. When the first is a string that contains '%', it is treated like fmt.Sprintf. +// - formatWithArgs are optional. When the first is a string that contains '%', it is treated like fmt.Sprintf. func Error(t TestingT, err error, formatWithArgs ...interface{}) { if err == nil { fail(t, "expected an error, but was nil", "", formatWithArgs...) @@ -111,7 +111,7 @@ func Error(t TestingT, err error, formatWithArgs ...interface{}) { // ErrorIs fails if the err is nil or errors.Is fails against the expected. // -// * formatWithArgs are optional. When the first is a string that contains '%', it is treated like fmt.Sprintf. +// - formatWithArgs are optional. When the first is a string that contains '%', it is treated like fmt.Sprintf. func ErrorIs(t TestingT, err, target error, formatWithArgs ...interface{}) { if err == nil { fail(t, "expected an error, but was nil", "", formatWithArgs...) @@ -124,7 +124,7 @@ func ErrorIs(t TestingT, err, target error, formatWithArgs ...interface{}) { // False fails if the actual value was true. // -// * formatWithArgs are optional. When the first is a string that contains '%', it is treated like fmt.Sprintf. +// - formatWithArgs are optional. When the first is a string that contains '%', it is treated like fmt.Sprintf. func False(t TestingT, actual bool, formatWithArgs ...interface{}) { if actual { fail(t, "expected false, but was true", "", formatWithArgs...) @@ -133,7 +133,7 @@ func False(t TestingT, actual bool, formatWithArgs ...interface{}) { // Nil fails if the object is not nil. // -// * formatWithArgs are optional. When the first is a string that contains '%', it is treated like fmt.Sprintf. +// - formatWithArgs are optional. When the first is a string that contains '%', it is treated like fmt.Sprintf. func Nil(t TestingT, object interface{}, formatWithArgs ...interface{}) { if !isNil(object) { fail(t, fmt.Sprintf("expected nil, but was %v", object), "", formatWithArgs...) @@ -142,7 +142,7 @@ func Nil(t TestingT, object interface{}, formatWithArgs ...interface{}) { // NoError fails if the err is not nil. // -// * formatWithArgs are optional. When the first is a string that contains '%', it is treated like fmt.Sprintf. +// - formatWithArgs are optional. When the first is a string that contains '%', it is treated like fmt.Sprintf. func NoError(t TestingT, err error, formatWithArgs ...interface{}) { if err != nil { fail(t, fmt.Sprintf("expected no error, but was %v", err), "", formatWithArgs...) @@ -151,7 +151,7 @@ func NoError(t TestingT, err error, formatWithArgs ...interface{}) { // NotEqual fails if the actual value is equal to the expected. // -// * formatWithArgs are optional. When the first is a string that contains '%', it is treated like fmt.Sprintf. +// - formatWithArgs are optional. When the first is a string that contains '%', it is treated like fmt.Sprintf. func NotEqual(t TestingT, expected, actual interface{}, formatWithArgs ...interface{}) { if !equal(expected, actual) { return @@ -166,7 +166,7 @@ func NotEqual(t TestingT, expected, actual interface{}, formatWithArgs ...interf // NotNil fails if the object is nil. // -// * formatWithArgs are optional. When the first is a string that contains '%', it is treated like fmt.Sprintf. +// - formatWithArgs are optional. When the first is a string that contains '%', it is treated like fmt.Sprintf. func NotNil(t TestingT, object interface{}, formatWithArgs ...interface{}) { if isNil(object) { fail(t, "expected to not be nil", "", formatWithArgs...) @@ -194,7 +194,7 @@ func isNil(object interface{}) (isNil bool) { // NotSame fails if the inputs point to the same object. // -// * formatWithArgs are optional. When the first is a string that contains '%', it is treated like fmt.Sprintf. +// - formatWithArgs are optional. When the first is a string that contains '%', it is treated like fmt.Sprintf. func NotSame(t TestingT, expected, actual interface{}, formatWithArgs ...interface{}) { if equalsPointer(expected, actual) { fail(t, fmt.Sprintf("expected %v to point to a different object", actual), "", formatWithArgs...) @@ -219,7 +219,7 @@ func CapturePanic(panics func()) (err error) { // Same fails if the inputs don't point to the same object. // -// * formatWithArgs are optional. When the first is a string that contains '%', it is treated like fmt.Sprintf. +// - formatWithArgs are optional. When the first is a string that contains '%', it is treated like fmt.Sprintf. func Same(t TestingT, expected, actual interface{}, formatWithArgs ...interface{}) { if !equalsPointer(expected, actual) { fail(t, fmt.Sprintf("expected %v to point to the same object as %v", actual, expected), "", formatWithArgs...) @@ -246,7 +246,7 @@ func equalsPointer(expected, actual interface{}) bool { // True fails if the actual value wasn't. // -// * formatWithArgs are optional. When the first is a string that contains '%', it is treated like fmt.Sprintf. +// - formatWithArgs are optional. When the first is a string that contains '%', it is treated like fmt.Sprintf. func True(t TestingT, actual bool, formatWithArgs ...interface{}) { if !actual { fail(t, "expected true, but was false", "", formatWithArgs...) @@ -255,7 +255,7 @@ func True(t TestingT, actual bool, formatWithArgs ...interface{}) { // Zero fails if the actual value wasn't. // -// * formatWithArgs are optional. When the first is a string that contains '%', it is treated like fmt.Sprintf. +// - formatWithArgs are optional. When the first is a string that contains '%', it is treated like fmt.Sprintf. // // Note: This isn't precise to numeric types, but we don't care as being more precise is more code and tests. func Zero(t TestingT, i interface{}, formatWithArgs ...interface{}) { diff --git a/internal/wasm/module.go b/internal/wasm/module.go index e9a5c3c6..1eeafa76 100644 --- a/internal/wasm/module.go +++ b/internal/wasm/module.go @@ -343,18 +343,18 @@ func (m *Module) validateFunctions(enabledFeatures Features, functions []Index, // // The criteria for which function indexes can be available for that instruction is vague in the spec: // -// * "References: the list of function indices that occur in the module outside functions and can hence be used to form references inside them." -// * https://www.w3.org/TR/2022/WD-wasm-core-2-20220419/valid/conventions.html#contexts -// * "Ref is the set funcidx(module with functions=ε, start=ε) , i.e., the set of function indices occurring in the module, except in its functions or start function." -// * https://www.w3.org/TR/2022/WD-wasm-core-2-20220419/valid/modules.html#valid-module +// - "References: the list of function indices that occur in the module outside functions and can hence be used to form references inside them." +// - https://www.w3.org/TR/2022/WD-wasm-core-2-20220419/valid/conventions.html#contexts +// - "Ref is the set funcidx(module with functions=ε, start=ε) , i.e., the set of function indices occurring in the module, except in its functions or start function." +// - https://www.w3.org/TR/2022/WD-wasm-core-2-20220419/valid/modules.html#valid-module // // To clarify, we reverse-engineer logic required to pass the WebAssembly Core specification 2.0 test suite: // https://github.com/WebAssembly/spec/blob/d39195773112a22b245ffbe864bab6d1182ccb06/test/core/ref_func.wast#L78-L115 // // To summarize, the function indexes OpcodeRefFunc can refer include: -// * existing in an element section regardless of its mode (active, passive, declarative). -// * defined as globals whose value type is ValueRefFunc. -// * used as an exported function. +// - existing in an element section regardless of its mode (active, passive, declarative). +// - defined as globals whose value type is ValueRefFunc. +// - used as an exported function. // // See https://github.com/WebAssembly/reference-types/issues/31 // See https://github.com/WebAssembly/reference-types/issues/76 @@ -580,9 +580,9 @@ func (m *Module) buildGlobals(importedGlobals []*GlobalInstance) (globals []*Glo // functions in this module. // // Notes -// * This relies on data generated by Module.BuildFunctionDefinitions. -// * This is exported for tests that don't call Instantiate, notably only -// enginetest.go. +// - This relies on data generated by Module.BuildFunctionDefinitions. +// - This is exported for tests that don't call Instantiate, notably only +// enginetest.go. func (m *ModuleInstance) BuildFunctions(mod *Module, listeners []experimental.FunctionListener) (fns []*FunctionInstance) { fns = make([]*FunctionInstance, 0, len(mod.FunctionDefinitionSection)) for i := range mod.FunctionSection { diff --git a/internal/wasm/table.go b/internal/wasm/table.go index c14f947c..bc42bcb7 100644 --- a/internal/wasm/table.go +++ b/internal/wasm/table.go @@ -231,8 +231,8 @@ func (m *Module) validateTable(enabledFeatures Features, tables []*Table, maximu } // buildTable returns TableInstances if the module defines or imports a table. -// * importedTables: returned as `tables` unmodified. -// * importedGlobals: include all instantiated, imported globals. +// - importedTables: returned as `tables` unmodified. +// - importedGlobals: include all instantiated, imported globals. // // If the result `init` is non-nil, it is the `tableInit` parameter of Engine.NewModuleEngine. // diff --git a/internal/wasmdebug/debug.go b/internal/wasmdebug/debug.go index d0009238..78fda81f 100644 --- a/internal/wasmdebug/debug.go +++ b/internal/wasmdebug/debug.go @@ -18,10 +18,10 @@ import ( // FuncName returns the naming convention of "moduleName.funcName". // -// * moduleName is the possibly empty name the module was instantiated with. -// * funcName is the name in the Custom Name section. -// * funcIdx is the position in the function index namespace, prefixed with -// imported functions. +// - moduleName is the possibly empty name the module was instantiated with. +// - funcName is the name in the Custom Name section. +// - funcIdx is the position in the function index namespace, prefixed with +// imported functions. // // Note: "moduleName.$funcIdx" is used when the funcName is empty, as commonly // the case in TinyGo. diff --git a/internal/watzero/internal/decoder.go b/internal/watzero/internal/decoder.go index 2cce6610..f17fa5f5 100644 --- a/internal/watzero/internal/decoder.go +++ b/internal/watzero/internal/decoder.go @@ -231,10 +231,12 @@ func (p *moduleParser) beginModuleField(tok tokenType, tokenBytes []byte, _, _ u // parseModuleName records the wasm.NameSection ModuleName, if present, and resumes with parseModule. // // Ex. A module name is present `(module $math)` -// records math --^ +// +// records math --^ // // Ex. No module name `(module)` -// calls parseModule here --^ +// +// calls parseModule here --^ func (p *moduleParser) parseModuleName(tok tokenType, tokenBytes []byte, line, col uint32) (tokenParser, error) { if tok == tokenID { // Ex. $Math p.module.NameSection.ModuleName = string(stripDollar(tokenBytes)) @@ -269,11 +271,13 @@ func (p *moduleParser) onTypeEnd(ft *wasm.FunctionType) tokenParser { // parseImportModule returns parseImportName after recording the import module name, or errs if it couldn't be read. // // Ex. Imported module name is present `(import "Math" "PI" (func (result f32)))` -// records Math --^ ^ -// parseImportName resumes here --+ +// +// records Math --^ ^ +// parseImportName resumes here --+ // // Ex. Imported module name is absent `(import (func (result f32)))` -// errs here --^ +// +// errs here --^ func (p *moduleParser) parseImportModule(tok tokenType, tokenBytes []byte, _, _ uint32) (tokenParser, error) { switch tok { case tokenString: // Ex. "" or "Math" @@ -290,12 +294,14 @@ func (p *moduleParser) parseImportModule(tok tokenType, tokenBytes []byte, _, _ // parseImportName returns parseImport after recording the import name, or errs if it couldn't be read. // // Ex. Import name is present `(import "Math" "PI" (func (result f32)))` -// starts here --^^ ^ -// records PI --+ | -// parseImport resumes here --+ +// +// starts here --^^ ^ +// records PI --+ | +// parseImport resumes here --+ // // Ex. Imported function name is absent `(import "Math" (func (result f32)))` -// errs here --+ +// +// errs here --+ func (p *moduleParser) parseImportName(tok tokenType, tokenBytes []byte, _, _ uint32) (tokenParser, error) { switch tok { case tokenString: // Ex. "" or "PI" @@ -346,11 +352,13 @@ func (p *moduleParser) beginImportDesc(tok tokenType, tokenBytes []byte, _, _ ui // parseImportFuncID records the ID of the current imported function, if present, and resumes with parseImportFunc. // // Ex. A function ID is present `(import "Math" "PI" (func $math.pi (result f32))` -// records math.pi here --^ -// parseImportFunc resumes here --^ +// +// records math.pi here --^ +// parseImportFunc resumes here --^ // // Ex. No function ID `(import "Math" "PI" (func (result f32))` -// calls parseImportFunc here --^ +// +// calls parseImportFunc here --^ func (p *moduleParser) parseImportFuncID(tok tokenType, tokenBytes []byte, line, col uint32) (tokenParser, error) { if tok == tokenID { // Ex. $main if name, err := p.funcNamespace.setID(tokenBytes); err != nil { @@ -376,11 +384,13 @@ func (p *moduleParser) addFunctionName(name string) { // parseImportFunc passes control to the typeUseParser until any signature is read, then returns onImportFunc. // // Ex. `(import "Math" "PI" (func $math.pi (result f32)))` -// starts here --^ ^ -// onImportFunc resumes here --+ +// +// starts here --^ ^ +// onImportFunc resumes here --+ // // Ex. If there is no signature `(import "" "main" (func))` -// calls onImportFunc here ---^ +// +// calls onImportFunc here ---^ func (p *moduleParser) parseImportFunc(tok tokenType, tokenBytes []byte, line, col uint32) (tokenParser, error) { if tok == tokenID { // Ex. (func $main $main) return nil, fmt.Errorf("redundant ID %s", tokenBytes) @@ -467,12 +477,14 @@ func (p *moduleParser) endMemory(mem *wasm.Memory) tokenParser { // parseExportName returns parseExport after recording the export name, or errs if it couldn't be read. // // Ex. Export name is present `(export "PI" (func 0))` -// starts here --^ ^ -// records PI --^ | -// parseExport resumes here --+ +// +// starts here --^ ^ +// records PI --^ | +// parseExport resumes here --+ // // Ex. Export name is absent `(export (func 0))` -// errs here --^ +// +// errs here --^ func (p *moduleParser) parseExportName(tok tokenType, tokenBytes []byte, _, _ uint32) (tokenParser, error) { switch tok { case tokenString: // Ex. "" or "PI" diff --git a/internal/watzero/internal/errors.go b/internal/watzero/internal/errors.go index 214a17b2..ec7c02d7 100644 --- a/internal/watzero/internal/errors.go +++ b/internal/watzero/internal/errors.go @@ -61,7 +61,8 @@ func importAfterModuleDefined(section wasm.SectionID) error { // Ex. All of these fail because they result in two memories. // * `(module (memory 1) (memory 1))` // * `(module (memory 1) (import "" "" (memory 1)))` -// * Note the latter expands to the same as the former: `(import "" "" (memory 1))` +// - Note the latter expands to the same as the former: `(import "" "" (memory 1))` +// // * `(module (import "" "" (memory 1)) (import "" "" (memory 1)))` // // See https://www.w3.org/TR/2019/REC-wasm-core-1-20191205/#tables%E2%91%A0 diff --git a/internal/watzero/internal/func_parser.go b/internal/watzero/internal/func_parser.go index 64c355fa..2f312540 100644 --- a/internal/watzero/internal/func_parser.go +++ b/internal/watzero/internal/func_parser.go @@ -19,8 +19,9 @@ type onFunc func(typeIdx wasm.Index, code *wasm.Code, name string, localNames wa // funcParser parses any instructions and dispatches to onFunc. // // Ex. `(module (func (nop)))` -// begin here --^ ^ -// end calls onFunc here --+ +// +// begin here --^ ^ +// end calls onFunc here --+ // // Note: funcParser is reusable. The caller resets via begin. type funcParser struct { @@ -55,11 +56,13 @@ var codeEnd = &wasm.Code{Body: end} // This stage records the ID of the current function, if present, and resumes with onFunc. // // Ex. A func ID is present `(func $main nop)` -// records main --^ ^ -// parseFunc resumes here --+ +// +// records main --^ ^ +// parseFunc resumes here --+ // // Ex. No func ID `(func nop)` -// calls parseFunc --^ +// +// calls parseFunc --^ func (p *funcParser) begin(tok tokenType, tokenBytes []byte, line, col uint32) (tokenParser, error) { if tok == tokenID { // Ex. $main if id, err := p.funcNamespace.setID(tokenBytes); err != nil { @@ -77,16 +80,19 @@ func (p *funcParser) begin(tok tokenType, tokenBytes []byte, line, col uint32) ( // are read. Finally, this finishes via endFunc. // // Ex. `(module (func $math.pi (result f32))` -// begin here --^ ^ -// endFunc resumes here --+ +// +// begin here --^ ^ +// endFunc resumes here --+ // // Ex. `(module (func $math.pi (result f32) (local i32) )` -// begin here --^ ^ ^ -// funcParser.afterTypeUse resumes here --+ | -// endFunc resumes here --+ +// +// begin here --^ ^ ^ +// funcParser.afterTypeUse resumes here --+ | +// endFunc resumes here --+ // // Ex. If there is no signature `(func)` -// calls endFunc here ---^ +// +// calls endFunc here ---^ func (p *funcParser) parseFunc(tok tokenType, tokenBytes []byte, line, col uint32) (tokenParser, error) { if tok == tokenID { // Ex. (func $main $main) return nil, fmt.Errorf("redundant ID %s", tokenBytes) @@ -100,8 +106,9 @@ func (p *funcParser) parseFunc(tok tokenType, tokenBytes []byte, line, col uint3 // The onFunc field is invoked once any instructions are written into currentBody. // // Ex. Given the source `(module (func nop))` -// afterTypeUse starts here --^ ^ -// calls onFunc here --+ +// +// afterTypeUse starts here --^ ^ +// calls onFunc here --+ func (p *funcParser) afterTypeUse(typeIdx wasm.Index, paramNames wasm.NameMap, pos callbackPosition, tok tokenType, tokenBytes []byte, line, col uint32) (tokenParser, error) { switch pos { case callbackPositionEndField: diff --git a/internal/watzero/internal/index_namespace.go b/internal/watzero/internal/index_namespace.go index 0e192fd3..964fb1fb 100644 --- a/internal/watzero/internal/index_namespace.go +++ b/internal/watzero/internal/index_namespace.go @@ -146,7 +146,8 @@ type unresolvedIndex struct { // // Failure cases are when a symbolic identifier points nowhere or a numeric index is out of range. // Ex. (start $t0) exists, but there's no import or module-defined function with that name. -// or (start 32) exists, but there are only 10 functions. +// +// or (start 32) exists, but there are only 10 functions. func (i *indexNamespace) resolve(unresolved *unresolvedIndex) (wasm.Index, error) { if unresolved.targetID == "" { // already bound to a numeric index, but we have to verify it is in range if err := requireIndexInRange(unresolved.targetIdx, i.count); err != nil { diff --git a/internal/watzero/internal/memory_parser.go b/internal/watzero/internal/memory_parser.go index 94e07e5d..fbc53364 100644 --- a/internal/watzero/internal/memory_parser.go +++ b/internal/watzero/internal/memory_parser.go @@ -20,8 +20,9 @@ type onMemory func(*wasm.Memory) tokenParser // memoryParser parses an api.Memory from and dispatches to onMemory. // // Ex. `(module (memory 0 1024))` -// starts here --^ ^ -// onMemory resumes here --+ +// +// starts here --^ ^ +// onMemory resumes here --+ // // Note: memoryParser is reusable. The caller resets via begin. // See https://www.w3.org/TR/2019/REC-wasm-core-1-20191205/#memories%E2%91%A7 @@ -43,11 +44,13 @@ type memoryParser struct { // This stage records the ID of the current memory, if present, and resumes with beginMin. // // Ex. A memory ID is present `(memory $mem 0)` -// records mem --^ ^ -// beginMin resumes here --+ +// +// records mem --^ ^ +// beginMin resumes here --+ // // Ex. No memory ID `(memory 0)` -// calls beginMin --^ +// +// calls beginMin --^ func (p *memoryParser) begin(tok tokenType, tokenBytes []byte, line, col uint32) (tokenParser, error) { p.currentMemory = &wasm.Memory{} if tok == tokenID { // Ex. $mem diff --git a/internal/watzero/internal/type_parser.go b/internal/watzero/internal/type_parser.go index e6cc0a68..289ad79b 100644 --- a/internal/watzero/internal/type_parser.go +++ b/internal/watzero/internal/type_parser.go @@ -16,8 +16,9 @@ type onType func(ft *wasm.FunctionType) tokenParser // typeParser parses a wasm.Type from and dispatches to onType. // // Ex. `(module (type (func (param i32) (result i64)))` -// starts here --^ ^ -// onType resumes here --+ +// +// starts here --^ ^ +// onType resumes here --+ // // Note: typeParser is reusable. The caller resets via begin. type typeParser struct { @@ -58,11 +59,13 @@ type typeParser struct { // This stage records the ID of the current type, if present, and resumes with tryBeginFunc. // // Ex. A type ID is present `(type $t0 (func (result i32)))` -// records t0 --^ ^ -// tryBeginFunc resumes here --+ +// +// records t0 --^ ^ +// tryBeginFunc resumes here --+ // // Ex. No type ID `(type (func (result i32)))` -// calls tryBeginFunc --^ +// +// calls tryBeginFunc --^ func (p *typeParser) begin(tok tokenType, tokenBytes []byte, line, col uint32) (tokenParser, error) { p.currentType = &wasm.FunctionType{} if tok == tokenID { // Ex. $v_v @@ -105,11 +108,13 @@ func (p *typeParser) beginFunc(tok tokenType, tokenBytes []byte, _, _ uint32) (t // parseFunc passes control to the typeParser until any signature is read, then returns parseFuncEnd. // // Ex. `(module (type $rf32 (func (result f32))))` -// starts here --^ ^ -// parseFuncEnd resumes here --+ +// +// starts here --^ ^ +// parseFuncEnd resumes here --+ // // Ex. If there is no signature `(module (type $rf32 ))` -// calls parseFuncEnd here ---^ +// +// calls parseFuncEnd here ---^ func (p *typeParser) parseFunc(tok tokenType, tokenBytes []byte, line, col uint32) (tokenParser, error) { switch tok { case tokenLParen: @@ -207,11 +212,13 @@ func (p *typeParser) beginResult(tok tokenType, tokenBytes []byte, _, _ uint32) // parseParamID ignores any ID if present and resumes with parseParam . // // Ex. A param ID is present `(param $x i32)` -// ^ -// parseParam resumes here --+ +// +// ^ +// parseParam resumes here --+ // // Ex. No param ID `(param i32)` -// calls parseParam --^ +// +// calls parseParam --^ func (p *typeParser) parseParamID(tok tokenType, tokenBytes []byte, line, col uint32) (tokenParser, error) { if tok == tokenID { // Ex. $len p.parsedParamID = true @@ -224,13 +231,15 @@ func (p *typeParser) parseParamID(tok tokenType, tokenBytes []byte, line, col ui // this returns parseMoreParamsOrResult. // // Ex. One param type is present `(param i32)` -// records i32 --^ ^ -// parseMoreParamsOrResult resumes here --+ +// +// records i32 --^ ^ +// parseMoreParamsOrResult resumes here --+ // // Ex. Multiple param types are present `(param i32 i64)` -// records i32 --^ ^ ^ -// records i32 --+ | -// parseMoreParamsOrResult resumes here --+ +// +// records i32 --^ ^ ^ +// records i32 --+ | +// parseMoreParamsOrResult resumes here --+ func (p *typeParser) parseParam(tok tokenType, tokenBytes []byte, _, _ uint32) (tokenParser, error) { switch tok { case tokenID: // Ex. $len @@ -260,13 +269,15 @@ func (p *typeParser) parseParam(tok tokenType, tokenBytes []byte, _, _ uint32) ( // this returns parseMoreResults. // // Ex. One result type is present `(result i32)` -// records i32 --^ ^ -// parseMoreResults resumes here --+ +// +// records i32 --^ ^ +// parseMoreResults resumes here --+ // // Ex. Multiple result types are present `(result i32 i64)` -// records i32 --^ ^ ^ -// records i32 --+ | -// parseMoreResults resumes here --+ +// +// records i32 --^ ^ ^ +// records i32 --+ | +// parseMoreResults resumes here --+ func (p *typeParser) parseResult(tok tokenType, tokenBytes []byte, _, _ uint32) (tokenParser, error) { switch tok { case tokenID: // Ex. $len diff --git a/internal/watzero/internal/typeuse_parser.go b/internal/watzero/internal/typeuse_parser.go index 1f3d77b9..4172d3fe 100644 --- a/internal/watzero/internal/typeuse_parser.go +++ b/internal/watzero/internal/typeuse_parser.go @@ -24,8 +24,9 @@ type onTypeUse func(typeIdx wasm.Index, paramNames wasm.NameMap, pos callbackPos // typeUseParser parses an inlined type from a field such wasm.ExternTypeFuncName and calls onTypeUse. // // Ex. `(import "Math" "PI" (func $math.pi (result f32)))` -// starts here --^ ^ -// onTypeUse resumes here --+ +// +// starts here --^ ^ +// onTypeUse resumes here --+ // // Note: Unlike normal parsers, this is not used for an entire field (enclosed by parens). Rather, this only handles // "type", "param" and "result" inner fields in the correct order. @@ -96,13 +97,14 @@ type typeUseParser struct { // to ensure a valid empty type use is associated with the section index, if needed. // // Ex. Given the source `(module (import (func $main (param i32))))` -// beginTypeParamOrResult starts here --^ ^ -// onTypeUse resumes here --+ +// +// beginTypeParamOrResult starts here --^ ^ +// onTypeUse resumes here --+ // // Ex. Given the source `(module (func $main (result i32) (local.get 0))` -// beginTypeParamOrResult starts here --^ ^ -// onTypeUse resumes here --+ // +// beginTypeParamOrResult starts here --^ ^ +// onTypeUse resumes here --+ func (p *typeUseParser) begin(section wasm.SectionID, onTypeUse onTypeUse, tok tokenType, tokenBytes []byte, line, col uint32) (tokenParser, error) { pos := callbackPositionUnhandledToken p.pos = positionInitial // to ensure errorContext reports properly @@ -266,11 +268,13 @@ func (p *typeUseParser) beginResult(tok tokenType, tokenBytes []byte, line, col // parseParamID sets any ID if present and resumes with parseParam . // // Ex. A param ID is present `(param $x i32)` -// ^ -// parseParam resumes here --+ +// +// ^ +// parseParam resumes here --+ // // Ex. No param ID `(param i32)` -// calls parseParam --^ +// +// calls parseParam --^ func (p *typeUseParser) parseParamID(tok tokenType, tokenBytes []byte, line, col uint32) (tokenParser, error) { if tok == tokenID { // Ex. $len if err := p.setParamID(tokenBytes); err != nil { @@ -307,13 +311,15 @@ func (p *typeUseParser) setParamID(idToken []byte) error { // this returns parseMoreParamsOrResult. // // Ex. One param type is present `(param i32)` -// records i32 --^ ^ -// parseMoreParamsOrResult resumes here --+ +// +// records i32 --^ ^ +// parseMoreParamsOrResult resumes here --+ // // Ex. Multiple param types are present `(param i32 i64)` -// records i32 --^ ^ ^ -// records i32 --+ | -// parseMoreParamsOrResult resumes here --+ +// +// records i32 --^ ^ ^ +// records i32 --+ | +// parseMoreParamsOrResult resumes here --+ func (p *typeUseParser) parseParam(tok tokenType, tokenBytes []byte, _, _ uint32) (tokenParser, error) { switch tok { case tokenID: // Ex. $len @@ -347,13 +353,15 @@ func (p *typeUseParser) parseParam(tok tokenType, tokenBytes []byte, _, _ uint32 // this returns parseMoreResults. // // Ex. One result type is present `(result i32)` -// records i32 --^ ^ -// parseMoreResults resumes here --+ +// +// records i32 --^ ^ +// parseMoreResults resumes here --+ // // Ex. Multiple result types are present `(result i32 i64)` -// records i32 --^ ^ ^ -// records i32 --+ | -// parseMoreResults resumes here --+ +// +// records i32 --^ ^ ^ +// records i32 --+ | +// parseMoreResults resumes here --+ func (p *typeUseParser) parseResult(tok tokenType, tokenBytes []byte, _, _ uint32) (tokenParser, error) { switch tok { case tokenID: // Ex. $len @@ -496,7 +504,9 @@ func (p *typeUseParser) recordInlinedType(inlinedIdx wasm.Index) { } // requireInlinedMatchesReferencedType satisfies the following rule: +// // >> If inline declarations are given, then their types must match the referenced function type. +// // See https://www.w3.org/TR/2019/REC-wasm-core-1-20191205/#type-uses%E2%91%A0 func requireInlinedMatchesReferencedType(typeSection []*wasm.FunctionType, index wasm.Index, params, results []wasm.ValueType) error { if !typeSection[index].EqualsSignature(params, results) { diff --git a/internal/watzero/watzero.go b/internal/watzero/watzero.go index b98d98ba..6b98770a 100644 --- a/internal/watzero/watzero.go +++ b/internal/watzero/watzero.go @@ -10,8 +10,8 @@ import ( // This function returns when the input is exhausted or an error occurs. // // Here's a description of the return values: -// * result is the module parsed or nil on error -// * err is an error invoking the parser, dangling block comments or unexpected characters. +// - result is the module parsed or nil on error +// - err is an error invoking the parser, dangling block comments or unexpected characters. // // See https://www.w3.org/TR/2019/REC-wasm-core-1-20191205/#text-format%E2%91%A0 func Wat2Wasm(wat string) ([]byte, error) { diff --git a/internal/watzero/watzero_test.go b/internal/watzero/watzero_test.go index 965ae1d1..bbd35314 100644 --- a/internal/watzero/watzero_test.go +++ b/internal/watzero/watzero_test.go @@ -13,6 +13,7 @@ import ( var example = newExample() // exampleWat is different from exampleWat because the parser doesn't yet support all features. +// //go:embed testdata/example.wat var exampleWat string diff --git a/internal/wazeroir/compiler.go b/internal/wazeroir/compiler.go index a6538d0c..6550ce04 100644 --- a/internal/wazeroir/compiler.go +++ b/internal/wazeroir/compiler.go @@ -159,7 +159,7 @@ type compiler struct { } // For debugging only. -//nolint +// nolint func (c *compiler) stackDump() string { strs := make([]string, 0, len(c.stack)) for _, s := range c.stack { diff --git a/internal/wazeroir/operations.go b/internal/wazeroir/operations.go index 1ca8022f..22503a9b 100644 --- a/internal/wazeroir/operations.go +++ b/internal/wazeroir/operations.go @@ -1080,7 +1080,7 @@ func (OperationLoad32) Kind() OperationKind { // OperationStore implements Operation. // -// This corresponds to wasm.OpcodeI32StoreName wasm.OpcodeI64StoreName wasm.OpcodeF32StoreName wasm.OpcodeF64StoreName +// # This corresponds to wasm.OpcodeI32StoreName wasm.OpcodeI64StoreName wasm.OpcodeF32StoreName wasm.OpcodeF64StoreName // // The engines are expected to check the boundary of memory length, and exit the execution if this exceeds the boundary, // otherwise store the corresponding value following the semantics of the corresponding WebAssembly instruction. @@ -1096,7 +1096,7 @@ func (*OperationStore) Kind() OperationKind { // OperationStore8 implements Operation. // -// This corresponds to wasm.OpcodeI32Store8Name wasm.OpcodeI64Store8Name +// # This corresponds to wasm.OpcodeI32Store8Name wasm.OpcodeI64Store8Name // // The engines are expected to check the boundary of memory length, and exit the execution if this exceeds the boundary, // otherwise store the corresponding value following the semantics of the corresponding WebAssembly instruction. @@ -1111,7 +1111,7 @@ func (OperationStore8) Kind() OperationKind { // OperationStore16 implements Operation. // -// This corresponds to wasm.OpcodeI32Store16Name wasm.OpcodeI64Store16Name +// # This corresponds to wasm.OpcodeI32Store16Name wasm.OpcodeI64Store16Name // // The engines are expected to check the boundary of memory length, and exit the execution if this exceeds the boundary, // otherwise store the corresponding value following the semantics of the corresponding WebAssembly instruction. @@ -1126,7 +1126,7 @@ func (OperationStore16) Kind() OperationKind { // OperationStore32 implements Operation. // -// This corresponds to wasm.OpcodeI64Store32Name +// # This corresponds to wasm.OpcodeI64Store32Name // // The engines are expected to check the boundary of memory length, and exit the execution if this exceeds the boundary, // otherwise store the corresponding value following the semantics of the corresponding WebAssembly instruction. @@ -1351,6 +1351,7 @@ func (OperationPopcnt) Kind() OperationKind { // OperationDiv implements Operation. // // This corresponds to wasm.OpcodeI32DivS wasm.OpcodeI32DivU wasm.OpcodeI64DivS +// // wasm.OpcodeI64DivU wasm.OpcodeF32Div wasm.OpcodeF64Div. type OperationDiv struct{ Type SignedType } @@ -1376,7 +1377,7 @@ func (OperationRem) Kind() OperationKind { // OperationAnd implements Operation. // -// This corresponds to wasm.OpcodeI32AndName wasm.OpcodeI64AndName +// # This corresponds to wasm.OpcodeI32AndName wasm.OpcodeI64AndName // // The engines are expected to perform "And" operation on // top two values on the stack, and pushes the result. @@ -1389,7 +1390,7 @@ func (OperationAnd) Kind() OperationKind { // OperationOr implements Operation. // -// This corresponds to wasm.OpcodeI32OrName wasm.OpcodeI64OrName +// # This corresponds to wasm.OpcodeI32OrName wasm.OpcodeI64OrName // // The engines are expected to perform "Or" operation on // top two values on the stack, and pushes the result. @@ -1402,7 +1403,7 @@ func (OperationOr) Kind() OperationKind { // OperationXor implements Operation. // -// This corresponds to wasm.OpcodeI32XorName wasm.OpcodeI64XorName +// # This corresponds to wasm.OpcodeI32XorName wasm.OpcodeI64XorName // // The engines are expected to perform "Xor" operation on // top two values on the stack, and pushes the result. @@ -1415,7 +1416,7 @@ func (OperationXor) Kind() OperationKind { // OperationShl implements Operation. // -// This corresponds to wasm.OpcodeI32ShlName wasm.OpcodeI64ShlName +// # This corresponds to wasm.OpcodeI32ShlName wasm.OpcodeI64ShlName // // The engines are expected to perform "Shl" operation on // top two values on the stack, and pushes the result. @@ -1428,7 +1429,7 @@ func (OperationShl) Kind() OperationKind { // OperationShr implements Operation. // -// This corresponds to wasm.OpcodeI32ShrSName wasm.OpcodeI32ShrUName wasm.OpcodeI64ShrSName wasm.OpcodeI64ShrUName +// # This corresponds to wasm.OpcodeI32ShrSName wasm.OpcodeI32ShrUName wasm.OpcodeI64ShrSName wasm.OpcodeI64ShrUName // // If OperationShr.Type is signed integer, then, the engines are expected to perform arithmetic right shift on the two // top values on the stack, otherwise do the logical right shift. @@ -1441,7 +1442,7 @@ func (OperationShr) Kind() OperationKind { // OperationRotl implements Operation. // -// This corresponds to wasm.OpcodeI32RotlName wasm.OpcodeI64RotlName +// # This corresponds to wasm.OpcodeI32RotlName wasm.OpcodeI64RotlName // // The engines are expected to perform "Rotl" operation on // top two values on the stack, and pushes the result. @@ -1454,7 +1455,7 @@ func (OperationRotl) Kind() OperationKind { // OperationRotr implements Operation. // -// This corresponds to wasm.OpcodeI32RotrName wasm.OpcodeI64RotrName +// # This corresponds to wasm.OpcodeI32RotrName wasm.OpcodeI64RotrName // // The engines are expected to perform "Rotr" operation on // top two values on the stack, and pushes the result. @@ -1517,7 +1518,7 @@ func (OperationTrunc) Kind() OperationKind { // OperationNearest implements Operation. // -// This corresponds to wasm.OpcodeF32NearestName wasm.OpcodeF64NearestName +// # This corresponds to wasm.OpcodeF32NearestName wasm.OpcodeF64NearestName // // Note: this is *not* equivalent to math.Round and instead has the same // the semantics of LLVM's rint intrinsic. See https://llvm.org/docs/LangRef.html#llvm-rint-intrinsic. @@ -1541,7 +1542,7 @@ func (OperationSqrt) Kind() OperationKind { // OperationMin implements Operation. // -// This corresponds to wasm.OpcodeF32MinName wasm.OpcodeF64MinName +// # This corresponds to wasm.OpcodeF32MinName wasm.OpcodeF64MinName // // The engines are expected to pop two values from the stack, and push back the maximum of // these two values onto the stack. For example, stack [..., 100.1, 1.9] results in [..., 1.9]. @@ -1557,7 +1558,7 @@ func (OperationMin) Kind() OperationKind { // OperationMax implements Operation. // -// This corresponds to wasm.OpcodeF32MaxName wasm.OpcodeF64MaxName +// # This corresponds to wasm.OpcodeF32MaxName wasm.OpcodeF64MaxName // // The engines are expected to pop two values from the stack, and push back the maximum of // these two values onto the stack. For example, stack [..., 100.1, 1.9] results in [..., 100.1]. @@ -1573,7 +1574,7 @@ func (OperationMax) Kind() OperationKind { // OperationCopysign implements Operation. // -// This corresponds to wasm.OpcodeF32CopysignName wasm.OpcodeF64CopysignName +// # This corresponds to wasm.OpcodeF32CopysignName wasm.OpcodeF64CopysignName // // The engines are expected to pop two float values from the stack, and copy the signbit of // the first-popped value to the last one. @@ -1601,10 +1602,11 @@ func (OperationI32WrapFromI64) Kind() OperationKind { // OperationITruncFromF implements Operation. // // This corresponds to -// wasm.OpcodeI32TruncF32SName wasm.OpcodeI32TruncF32UName wasm.OpcodeI32TruncF64SName -// wasm.OpcodeI32TruncF64UName wasm.OpcodeI64TruncF32SName wasm.OpcodeI64TruncF32UName wasm.OpcodeI64TruncF64SName +// +// wasm.OpcodeI32TruncF32SName wasm.OpcodeI32TruncF32UName wasm.OpcodeI32TruncF64SName +// wasm.OpcodeI32TruncF64UName wasm.OpcodeI64TruncF32SName wasm.OpcodeI64TruncF32UName wasm.OpcodeI64TruncF64SName // wasm.OpcodeI64TruncF64UName. wasm.OpcodeI32TruncSatF32SName wasm.OpcodeI32TruncSatF32UName -// wasm.OpcodeI32TruncSatF64SName wasm.OpcodeI32TruncSatF64UName wasm.OpcodeI64TruncSatF32SName +// wasm.OpcodeI32TruncSatF64SName wasm.OpcodeI32TruncSatF64UName wasm.OpcodeI64TruncSatF32SName // wasm.OpcodeI64TruncSatF32UName wasm.OpcodeI64TruncSatF64SName wasm.OpcodeI64TruncSatF64UName // // See [1] and [2] for when we encounter undefined behavior in the WebAssembly specification if OperationITruncFromF.NonTrapping == false. @@ -1630,8 +1632,10 @@ func (OperationITruncFromF) Kind() OperationKind { // OperationFConvertFromI implements Operation. // // This corresponds to -// wasm.OpcodeF32ConvertI32SName wasm.OpcodeF32ConvertI32UName wasm.OpcodeF32ConvertI64SName wasm.OpcodeF32ConvertI64UName -// wasm.OpcodeF64ConvertI32SName wasm.OpcodeF64ConvertI32UName wasm.OpcodeF64ConvertI64SName wasm.OpcodeF64ConvertI64UName +// +// wasm.OpcodeF32ConvertI32SName wasm.OpcodeF32ConvertI32UName wasm.OpcodeF32ConvertI64SName wasm.OpcodeF32ConvertI64UName +// wasm.OpcodeF64ConvertI32SName wasm.OpcodeF64ConvertI32UName wasm.OpcodeF64ConvertI64SName wasm.OpcodeF64ConvertI64UName +// // and equivalent to float32(uint32(x)), float32(int32(x)), etc in Go. type OperationFConvertFromI struct { InputType SignedInt @@ -1705,7 +1709,7 @@ func (OperationF64ReinterpretFromI64) Kind() OperationKind { // OperationExtend implements Operation. // -// This corresponds to wasm.OpcodeI64ExtendI32SName wasm.OpcodeI64ExtendI32UName +// # This corresponds to wasm.OpcodeI64ExtendI32SName wasm.OpcodeI64ExtendI32UName // // The engines are expected to extend the 32-bit signed or unsigned int on top of the stack // as a 64-bit integer of corresponding signedness. For unsigned case, this is just reinterpreting the @@ -1988,7 +1992,8 @@ func shapeName(s Shape) (ret string) { // OperationV128Add implements Operation. // // This corresponds to wasm.OpcodeVecI8x16AddName wasm.OpcodeVecI16x8AddName wasm.OpcodeVecI32x4AddName -// wasm.OpcodeVecI64x2AddName wasm.OpcodeVecF32x4AddName wasm.OpcodeVecF64x2AddName +// +// wasm.OpcodeVecI64x2AddName wasm.OpcodeVecF32x4AddName wasm.OpcodeVecF64x2AddName type OperationV128Add struct { Shape Shape } @@ -2001,7 +2006,8 @@ func (OperationV128Add) Kind() OperationKind { // OperationV128Sub implements Operation. // // This corresponds to wasm.OpcodeVecI8x16SubName wasm.OpcodeVecI16x8SubName wasm.OpcodeVecI32x4SubName -// wasm.OpcodeVecI64x2SubName wasm.OpcodeVecF32x4SubName wasm.OpcodeVecF64x2SubName +// +// wasm.OpcodeVecI64x2SubName wasm.OpcodeVecF32x4SubName wasm.OpcodeVecF64x2SubName type OperationV128Sub struct { Shape Shape } @@ -2046,11 +2052,12 @@ const ( // OperationV128Load implements Operation. // // This corresponds to -// wasm.OpcodeVecV128LoadName wasm.OpcodeVecV128Load8x8SName wasm.OpcodeVecV128Load8x8UName -// wasm.OpcodeVecV128Load16x4SName wasm.OpcodeVecV128Load16x4UName wasm.OpcodeVecV128Load32x2SName -// wasm.OpcodeVecV128Load32x2UName wasm.OpcodeVecV128Load8SplatName wasm.OpcodeVecV128Load16SplatName -// wasm.OpcodeVecV128Load32SplatName wasm.OpcodeVecV128Load64SplatName wasm.OpcodeVecV128Load32zeroName -// wasm.OpcodeVecV128Load64zeroName +// +// wasm.OpcodeVecV128LoadName wasm.OpcodeVecV128Load8x8SName wasm.OpcodeVecV128Load8x8UName +// wasm.OpcodeVecV128Load16x4SName wasm.OpcodeVecV128Load16x4UName wasm.OpcodeVecV128Load32x2SName +// wasm.OpcodeVecV128Load32x2UName wasm.OpcodeVecV128Load8SplatName wasm.OpcodeVecV128Load16SplatName +// wasm.OpcodeVecV128Load32SplatName wasm.OpcodeVecV128Load64SplatName wasm.OpcodeVecV128Load32zeroName +// wasm.OpcodeVecV128Load64zeroName type OperationV128Load struct { Type V128LoadType Arg *MemoryArg @@ -2064,7 +2071,8 @@ func (OperationV128Load) Kind() OperationKind { // OperationV128LoadLane implements Operation. // // This corresponds to wasm.OpcodeVecV128Load8LaneName wasm.OpcodeVecV128Load16LaneName -// wasm.OpcodeVecV128Load32LaneName wasm.OpcodeVecV128Load64LaneName. +// +// wasm.OpcodeVecV128Load32LaneName wasm.OpcodeVecV128Load64LaneName. type OperationV128LoadLane struct { // LaneIndex is >=0 && <(128/LaneSize). LaneIndex byte @@ -2081,7 +2089,8 @@ func (OperationV128LoadLane) Kind() OperationKind { // OperationV128Store implements Operation. // // This corresponds to wasm.OpcodeVecV128Load8LaneName wasm.OpcodeVecV128Load16LaneName -// wasm.OpcodeVecV128Load32LaneName wasm.OpcodeVecV128Load64LaneName. +// +// wasm.OpcodeVecV128Load32LaneName wasm.OpcodeVecV128Load64LaneName. type OperationV128Store struct { Arg *MemoryArg } @@ -2094,7 +2103,8 @@ func (OperationV128Store) Kind() OperationKind { // OperationV128StoreLane implements Operation. // // This corresponds to wasm.OpcodeVecV128Load8LaneName wasm.OpcodeVecV128Load16LaneName -// wasm.OpcodeVecV128Load32LaneName wasm.OpcodeVecV128Load64LaneName. +// +// wasm.OpcodeVecV128Load32LaneName wasm.OpcodeVecV128Load64LaneName. type OperationV128StoreLane struct { // LaneIndex is >=0 && <(128/LaneSize). LaneIndex byte @@ -2111,9 +2121,10 @@ func (OperationV128StoreLane) Kind() OperationKind { // OperationV128ExtractLane implements Operation. // // This corresponds to -// wasm.OpcodeVecI8x16ExtractLaneSName wasm.OpcodeVecI8x16ExtractLaneUName -// wasm.OpcodeVecI16x8ExtractLaneSName wasm.OpcodeVecI16x8ExtractLaneUName -// wasm.OpcodeVecI32x4ExtractLaneName wasm.OpcodeVecI64x2ExtractLaneName +// +// wasm.OpcodeVecI8x16ExtractLaneSName wasm.OpcodeVecI8x16ExtractLaneUName +// wasm.OpcodeVecI16x8ExtractLaneSName wasm.OpcodeVecI16x8ExtractLaneUName +// wasm.OpcodeVecI32x4ExtractLaneName wasm.OpcodeVecI64x2ExtractLaneName // wasm.OpcodeVecF32x4ExtractLaneName wasm.OpcodeVecF64x2ExtractLaneName. type OperationV128ExtractLane struct { // LaneIndex is >=0 && =0 &&