From 03e20a1d1f3cfb6867488fef6800b1e77fd60fef Mon Sep 17 00:00:00 2001 From: Takeshi Yoneda Date: Thu, 27 Jun 2024 08:17:36 -0700 Subject: [PATCH 1/6] ci: merges spectests into normal make test Signed-off-by: Takeshi Yoneda --- .github/workflows/spectest.yaml | 92 --------------------------------- Makefile | 13 +---- README.md | 2 +- 3 files changed, 2 insertions(+), 105 deletions(-) delete mode 100644 .github/workflows/spectest.yaml diff --git a/.github/workflows/spectest.yaml b/.github/workflows/spectest.yaml deleted file mode 100644 index 7a0a5ef40e..0000000000 --- a/.github/workflows/spectest.yaml +++ /dev/null @@ -1,92 +0,0 @@ -name: WebAssembly Core Specification Test -on: - pull_request: - branches: [main] - paths-ignore: # ignore docs as they are built with Netlify. - - '**/*.md' - - 'site/**' - - 'netlify.toml' - push: - branches: [main] - paths-ignore: # ignore docs as they are built with Netlify. - - '**/*.md' - - 'site/**' - - 'netlify.toml' - -defaults: - run: # use bash for all operating systems unless overridden - shell: bash - -concurrency: - # https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#example-using-concurrency-to-cancel-any-in-progress-job-or-run - group: ${{ github.ref }}-${{ github.workflow }}-${{ github.actor }} - cancel-in-progress: true - -jobs: - test_amd64: - name: ${{ matrix.spec-version }} - linux/amd64, Go-${{ matrix.go-version }} - runs-on: ubuntu-22.04 - strategy: - fail-fast: false # don't fail fast as sometimes failures are arch/OS specific - matrix: # Use versions consistent with wazero's Go support policy. - go-version: - - "1.22" # Current Go version - - "1.20" # Floor Go version of wazero (current - 2) - spec-version: - - "v1" - - "v2" - - steps: - - uses: actions/checkout@v3 - - - uses: actions/setup-go@v4 - with: - go-version: ${{ matrix.go-version }} - - - run: make spectest.${{ matrix.spec-version }} - - test_scratch: - name: ${{ matrix.spec-version }} / ${{ matrix.arch }}, Go-${{ matrix.go-version }} - runs-on: ubuntu-22.04 - strategy: - fail-fast: false # don't fail fast as sometimes failures are arch/OS specific - matrix: # Use versions consistent with wazero's Go support policy. - go-version: - - "1.22" # Current Go version - - "1.20" # Floor Go version of wazero (current - 2) - arch: - - "arm64" - - "riscv64" - spec-version: - - "v1" - - "v2" - - steps: - - uses: actions/checkout@v3 - - - uses: actions/setup-go@v4 - with: - go-version: ${{ matrix.go-version }} - - - name: Build test binaries - run: go list -f '{{.Dir}}' ./... | grep 'spectest/${{ matrix.spec-version }}' | xargs -Ipkg go test pkg -c -o spectest.test - env: - GOARCH: ${{ matrix.arch }} - CGO_ENABLED: 0 - - - name: Set up QEMU - if: ${{ matrix.arch != 'amd64' }} - uses: docker/setup-qemu-action@v2 - with: # Avoid docker.io rate-limits; built with internal-images.yml - image: ghcr.io/tetratelabs/wazero/internal-binfmt - platforms: ${{ matrix.arch }} - - - name: Build scratch container - run: | - echo 'FROM scratch' >> Dockerfile - echo 'CMD ["/test"]' >> Dockerfile - docker buildx build -t wazero:test --platform linux/${{ matrix.arch }} . - - - name: Run built test binaries - # Note: This mounts /tmp to allow t.TempDir() in tests. - run: docker run --platform linux/${{ matrix.arch }} -v $(pwd)/spectest.test:/test --tmpfs /tmp --rm -t wazero:test diff --git a/Makefile b/Makefile index 0f60d2d5ff..d2f9a51cb4 100644 --- a/Makefile +++ b/Makefile @@ -167,7 +167,7 @@ build.spectest.threads: .PHONY: test test: - @go test $(go_test_options) $$(go list ./... | grep -vE '$(spectest_v1_dir)|$(spectest_v2_dir)') + @go test $(go_test_options) ./... @cd internal/version/testdata && go test $(go_test_options) ./... @cd internal/integration_test/fuzz/wazerolib && CGO_ENABLED=0 WASM_BINARY_PATH=testdata/test.wasm go test ./... @@ -178,17 +178,6 @@ coverage: ## Generate test coverage @go test -coverprofile=coverage.txt -covermode=atomic --coverpkg=$(coverpkg) $(main_packages) @go tool cover -func coverage.txt -.PHONY: spectest -spectest: - @$(MAKE) spectest.v1 - @$(MAKE) spectest.v2 - -spectest.v1: - @go test $(go_test_options) $$(go list ./... | grep $(spectest_v1_dir)) - -spectest.v2: - @go test $(go_test_options) $$(go list ./... | grep $(spectest_v2_dir)) - golangci_lint_path := $(shell go env GOPATH)/bin/golangci-lint $(golangci_lint_path): diff --git a/README.md b/README.md index 657da29594..f020be99a7 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # wazero: the zero dependency WebAssembly runtime for Go developers -[![WebAssembly Core Specification Test](https://github.com/tetratelabs/wazero/actions/workflows/spectest.yaml/badge.svg)](https://github.com/tetratelabs/wazero/actions/workflows/spectest.yaml) [![Go Reference](https://pkg.go.dev/badge/github.com/tetratelabs/wazero.svg)](https://pkg.go.dev/github.com/tetratelabs/wazero) [![License](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) +[![Go Reference](https://pkg.go.dev/badge/github.com/tetratelabs/wazero.svg)](https://pkg.go.dev/github.com/tetratelabs/wazero) [![License](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) WebAssembly is a way to safely run code compiled in other languages. Runtimes execute WebAssembly Modules (Wasm), which are most often binaries with a `.wasm` From 8d2aef5e7da1c4a195df42557b6f466a14f75d79 Mon Sep 17 00:00:00 2001 From: Takeshi Yoneda Date: Thu, 27 Jun 2024 14:18:35 -0700 Subject: [PATCH 2/6] debug log Signed-off-by: Takeshi Yoneda --- Makefile | 2 +- internal/engine/interpreter/interpreter.go | 22 ++++++++++++++-------- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/Makefile b/Makefile index d2f9a51cb4..a7d0a0faad 100644 --- a/Makefile +++ b/Makefile @@ -167,7 +167,7 @@ build.spectest.threads: .PHONY: test test: - @go test $(go_test_options) ./... + @go test $(go_test_options) ./internal/integration_test/spectest/v2/... -run=TestInterpreter/simd_i32x4_dot_i16x8.wast @cd internal/version/testdata && go test $(go_test_options) ./... @cd internal/integration_test/fuzz/wazerolib && CGO_ENABLED=0 WASM_BINARY_PATH=testdata/test.wasm go test ./... diff --git a/internal/engine/interpreter/interpreter.go b/internal/engine/interpreter/interpreter.go index 18c5f4252d..28c96c0fc1 100644 --- a/internal/engine/interpreter/interpreter.go +++ b/internal/engine/interpreter/interpreter.go @@ -3900,15 +3900,21 @@ func (ce *callEngine) callNativeFunc(ctx context.Context, m *wasm.ModuleInstance frame.pc++ case operationKindV128Dot: x2Hi, x2Lo := ce.popValue(), ce.popValue() + fmt.Printf("x2Hi: %x, x2Lo: %x\n", x2Hi, x2Lo) x1Hi, x1Lo := ce.popValue(), ce.popValue() - ce.pushValue( - uint64(uint32(int32(int16(x1Lo>>0))*int32(int16(x2Lo>>0))+int32(int16(x1Lo>>16))*int32(int16(x2Lo>>16)))) | - (uint64(uint32(int32(int16(x1Lo>>32))*int32(int16(x2Lo>>32))+int32(int16(x1Lo>>48))*int32(int16(x2Lo>>48)))) << 32), - ) - ce.pushValue( - uint64(uint32(int32(int16(x1Hi>>0))*int32(int16(x2Hi>>0))+int32(int16(x1Hi>>16))*int32(int16(x2Hi>>16)))) | - (uint64(uint32(int32(int16(x1Hi>>32))*int32(int16(x2Hi>>32))+int32(int16(x1Hi>>48))*int32(int16(x2Hi>>48)))) << 32), - ) + fmt.Printf("x1Hi: %x, x1Lo: %x\n", x1Hi, x1Lo) + r1 := int32(int16(x1Lo>>0)) * int32(int16(x2Lo>>0)) + r2 := int32(int16(x1Lo>>16)) * int32(int16(x2Lo>>16)) + r3 := int32(int16(x1Lo>>32)) * int32(int16(x2Lo>>32)) + r4 := int32(int16(x1Lo>>48)) * int32(int16(x2Lo>>48)) + fmt.Printf("r1: %x, r2: %x, r3: %x, r4: %x\n", r1, r2, r3, r4) + ce.pushValue(uint64(uint32(r1+r2)) | (uint64(uint32(r3+r4)) << 32)) + r5 := int32(int16(x1Hi>>0)) * int32(int16(x2Hi>>0)) + r6 := int32(int16(x1Hi>>16)) * int32(int16(x2Hi>>16)) + r7 := int32(int16(x1Hi>>32)) * int32(int16(x2Hi>>32)) + r8 := int32(int16(x1Hi>>48)) * int32(int16(x2Hi>>48)) + fmt.Printf("r5: %x, r6: %x, r7: %x, r8: %x\n", r5, r6, r7, r8) + ce.pushValue(uint64(uint32(r5+r6)) | (uint64(uint32(r7+r8)) << 32)) frame.pc++ case operationKindV128ITruncSatFromF: hi, lo := ce.popValue(), ce.popValue() From 1ef171d485096c9fff98c7f9ab4cc22c754243cd Mon Sep 17 00:00:00 2001 From: Takeshi Yoneda Date: Thu, 27 Jun 2024 14:22:20 -0700 Subject: [PATCH 3/6] done Signed-off-by: Takeshi Yoneda --- Makefile | 2 +- internal/engine/interpreter/interpreter.go | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/Makefile b/Makefile index a7d0a0faad..d2f9a51cb4 100644 --- a/Makefile +++ b/Makefile @@ -167,7 +167,7 @@ build.spectest.threads: .PHONY: test test: - @go test $(go_test_options) ./internal/integration_test/spectest/v2/... -run=TestInterpreter/simd_i32x4_dot_i16x8.wast + @go test $(go_test_options) ./... @cd internal/version/testdata && go test $(go_test_options) ./... @cd internal/integration_test/fuzz/wazerolib && CGO_ENABLED=0 WASM_BINARY_PATH=testdata/test.wasm go test ./... diff --git a/internal/engine/interpreter/interpreter.go b/internal/engine/interpreter/interpreter.go index 28c96c0fc1..a9568df4cb 100644 --- a/internal/engine/interpreter/interpreter.go +++ b/internal/engine/interpreter/interpreter.go @@ -3900,20 +3900,16 @@ func (ce *callEngine) callNativeFunc(ctx context.Context, m *wasm.ModuleInstance frame.pc++ case operationKindV128Dot: x2Hi, x2Lo := ce.popValue(), ce.popValue() - fmt.Printf("x2Hi: %x, x2Lo: %x\n", x2Hi, x2Lo) x1Hi, x1Lo := ce.popValue(), ce.popValue() - fmt.Printf("x1Hi: %x, x1Lo: %x\n", x1Hi, x1Lo) r1 := int32(int16(x1Lo>>0)) * int32(int16(x2Lo>>0)) r2 := int32(int16(x1Lo>>16)) * int32(int16(x2Lo>>16)) r3 := int32(int16(x1Lo>>32)) * int32(int16(x2Lo>>32)) r4 := int32(int16(x1Lo>>48)) * int32(int16(x2Lo>>48)) - fmt.Printf("r1: %x, r2: %x, r3: %x, r4: %x\n", r1, r2, r3, r4) ce.pushValue(uint64(uint32(r1+r2)) | (uint64(uint32(r3+r4)) << 32)) r5 := int32(int16(x1Hi>>0)) * int32(int16(x2Hi>>0)) r6 := int32(int16(x1Hi>>16)) * int32(int16(x2Hi>>16)) r7 := int32(int16(x1Hi>>32)) * int32(int16(x2Hi>>32)) r8 := int32(int16(x1Hi>>48)) * int32(int16(x2Hi>>48)) - fmt.Printf("r5: %x, r6: %x, r7: %x, r8: %x\n", r5, r6, r7, r8) ce.pushValue(uint64(uint32(r5+r6)) | (uint64(uint32(r7+r8)) << 32)) frame.pc++ case operationKindV128ITruncSatFromF: From 9e52d2bf3861db145fb9dba9be0e25ba05fa407d Mon Sep 17 00:00:00 2001 From: Takeshi Yoneda Date: Thu, 27 Jun 2024 15:24:09 -0700 Subject: [PATCH 4/6] fix Signed-off-by: Takeshi Yoneda --- internal/engine/interpreter/interpreter.go | 28 ++++++++++++++-------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/internal/engine/interpreter/interpreter.go b/internal/engine/interpreter/interpreter.go index a9568df4cb..9f0011d103 100644 --- a/internal/engine/interpreter/interpreter.go +++ b/internal/engine/interpreter/interpreter.go @@ -3901,16 +3901,9 @@ func (ce *callEngine) callNativeFunc(ctx context.Context, m *wasm.ModuleInstance case operationKindV128Dot: x2Hi, x2Lo := ce.popValue(), ce.popValue() x1Hi, x1Lo := ce.popValue(), ce.popValue() - r1 := int32(int16(x1Lo>>0)) * int32(int16(x2Lo>>0)) - r2 := int32(int16(x1Lo>>16)) * int32(int16(x2Lo>>16)) - r3 := int32(int16(x1Lo>>32)) * int32(int16(x2Lo>>32)) - r4 := int32(int16(x1Lo>>48)) * int32(int16(x2Lo>>48)) - ce.pushValue(uint64(uint32(r1+r2)) | (uint64(uint32(r3+r4)) << 32)) - r5 := int32(int16(x1Hi>>0)) * int32(int16(x2Hi>>0)) - r6 := int32(int16(x1Hi>>16)) * int32(int16(x2Hi>>16)) - r7 := int32(int16(x1Hi>>32)) * int32(int16(x2Hi>>32)) - r8 := int32(int16(x1Hi>>48)) * int32(int16(x2Hi>>48)) - ce.pushValue(uint64(uint32(r5+r6)) | (uint64(uint32(r7+r8)) << 32)) + lo, hi := v128Dot(x1Hi, x1Lo, x2Hi, x2Lo) + ce.pushValue(lo) + ce.pushValue(hi) frame.pc++ case operationKindV128ITruncSatFromF: hi, lo := ce.popValue(), ce.popValue() @@ -4586,3 +4579,18 @@ func (ce *callEngine) callGoFuncWithStack(ctx context.Context, m *wasm.ModuleIns ce.stack = ce.stack[0 : len(ce.stack)-shrinkLen] } } + +// v128Dot performs a dot product of two 64-bit vectors. +// Note: for some reason (which I suspect is due to a bug in Go compiler's regalloc), +// inlining this function causes a bug which **only happens** with -race. +func v128Dot(x1Hi, x1Lo, x2Hi, x2Lo uint64) (uint64, uint64) { + r1 := int32(int16(x1Lo>>0)) * int32(int16(x2Lo>>0)) + r2 := int32(int16(x1Lo>>16)) * int32(int16(x2Lo>>16)) + r3 := int32(int16(x1Lo>>32)) * int32(int16(x2Lo>>32)) + r4 := int32(int16(x1Lo>>48)) * int32(int16(x2Lo>>48)) + r5 := int32(int16(x1Hi>>0)) * int32(int16(x2Hi>>0)) + r6 := int32(int16(x1Hi>>16)) * int32(int16(x2Hi>>16)) + r7 := int32(int16(x1Hi>>32)) * int32(int16(x2Hi>>32)) + r8 := int32(int16(x1Hi>>48)) * int32(int16(x2Hi>>48)) + return uint64(uint32(r1+r2)) | (uint64(uint32(r3+r4)) << 32), uint64(uint32(r5+r6)) | (uint64(uint32(r7+r8)) << 32) +} From e57f6ccb008213ea5e930e25690d204ab8568151 Mon Sep 17 00:00:00 2001 From: Takeshi Yoneda Date: Thu, 27 Jun 2024 15:25:45 -0700 Subject: [PATCH 5/6] fix Signed-off-by: Takeshi Yoneda --- internal/engine/interpreter/interpreter.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/engine/interpreter/interpreter.go b/internal/engine/interpreter/interpreter.go index 9f0011d103..d0bfa2d1bb 100644 --- a/internal/engine/interpreter/interpreter.go +++ b/internal/engine/interpreter/interpreter.go @@ -4582,7 +4582,7 @@ func (ce *callEngine) callGoFuncWithStack(ctx context.Context, m *wasm.ModuleIns // v128Dot performs a dot product of two 64-bit vectors. // Note: for some reason (which I suspect is due to a bug in Go compiler's regalloc), -// inlining this function causes a bug which **only happens** with -race. +// inlining this function causes a bug which **only happens** with -race AND arm64. func v128Dot(x1Hi, x1Lo, x2Hi, x2Lo uint64) (uint64, uint64) { r1 := int32(int16(x1Lo>>0)) * int32(int16(x2Lo>>0)) r2 := int32(int16(x1Lo>>16)) * int32(int16(x2Lo>>16)) From 882a47b132eb3c28c20e379f78535e3354f92ce0 Mon Sep 17 00:00:00 2001 From: Takeshi Yoneda Date: Thu, 27 Jun 2024 15:31:19 -0700 Subject: [PATCH 6/6] fix Signed-off-by: Takeshi Yoneda --- internal/engine/interpreter/interpreter.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/engine/interpreter/interpreter.go b/internal/engine/interpreter/interpreter.go index d0bfa2d1bb..ee0b453ca0 100644 --- a/internal/engine/interpreter/interpreter.go +++ b/internal/engine/interpreter/interpreter.go @@ -4582,7 +4582,7 @@ func (ce *callEngine) callGoFuncWithStack(ctx context.Context, m *wasm.ModuleIns // v128Dot performs a dot product of two 64-bit vectors. // Note: for some reason (which I suspect is due to a bug in Go compiler's regalloc), -// inlining this function causes a bug which **only happens** with -race AND arm64. +// inlining this function causes a bug which happens **only when** we run with -race AND arm64 AND Go 1.22. func v128Dot(x1Hi, x1Lo, x2Hi, x2Lo uint64) (uint64, uint64) { r1 := int32(int16(x1Lo>>0)) * int32(int16(x2Lo>>0)) r2 := int32(int16(x1Lo>>16)) * int32(int16(x2Lo>>16))