From 6eb679c4e233eaa5e1a49e4eb8a72b06c9de3049 Mon Sep 17 00:00:00 2001 From: Takeshi Yoneda Date: Tue, 20 Feb 2024 11:36:40 +0900 Subject: [PATCH] wazevo(frontend): missing listener.After call in br_if target (#2078) Signed-off-by: Takeshi Yoneda --- internal/engine/wazevo/frontend/lower.go | 25 +++ .../integration_test/fuzz/wazerolib/extern.go | 3 +- .../fuzz/wazerolib/nodiff_test.go | 201 +---------------- .../fuzzcases/fuzzcases_test.go | 8 + .../fuzzcases/testdata/2078.wasm | Bin 0 -> 42 bytes .../fuzzcases/testdata/2078.wat | 12 + .../wazerolib => testing/nodiff}/nodiff.go | 13 +- internal/testing/nodiff/nodiff_test.go | 205 ++++++++++++++++++ 8 files changed, 264 insertions(+), 203 deletions(-) create mode 100644 internal/integration_test/fuzzcases/testdata/2078.wasm create mode 100644 internal/integration_test/fuzzcases/testdata/2078.wat rename internal/{integration_test/fuzz/wazerolib => testing/nodiff}/nodiff.go (97%) create mode 100644 internal/testing/nodiff/nodiff_test.go diff --git a/internal/engine/wazevo/frontend/lower.go b/internal/engine/wazevo/frontend/lower.go index cb58a00c58..b2a9111284 100644 --- a/internal/engine/wazevo/frontend/lower.go +++ b/internal/engine/wazevo/frontend/lower.go @@ -1498,12 +1498,37 @@ func (c *Compiler) lowerCurrentOpcode() { targetBlk, argNum := state.brTargetArgNumFor(labelIndex) args := c.nPeekDup(argNum) + var sealTargetBlk bool + if c.needListener && targetBlk.ReturnBlock() { // In this case, we have to call the listener before returning. + // Save the currently active block. + current := builder.CurrentBlock() + + // Allocate the trampoline block to the return where we call the listener. + targetBlk = builder.AllocateBasicBlock() + builder.SetCurrentBlock(targetBlk) + sealTargetBlk = true + + c.callListenerAfter() + + instr := builder.AllocateInstruction() + instr.AsReturn(args) + builder.InsertInstruction(instr) + + args = ssa.ValuesNil + + // Revert the current block. + builder.SetCurrentBlock(current) + } // Insert the conditional jump to the target block. brnz := builder.AllocateInstruction() brnz.AsBrnz(v, args, targetBlk) builder.InsertInstruction(brnz) + if sealTargetBlk { + builder.Seal(targetBlk) + } + // Insert the unconditional jump to the Else block which corresponds to after br_if. elseBlk := builder.AllocateBasicBlock() c.insertJumpToBlock(ssa.ValuesNil, elseBlk) diff --git a/internal/integration_test/fuzz/wazerolib/extern.go b/internal/integration_test/fuzz/wazerolib/extern.go index e3a4d06e8f..b00d3beabb 100644 --- a/internal/integration_test/fuzz/wazerolib/extern.go +++ b/internal/integration_test/fuzz/wazerolib/extern.go @@ -12,6 +12,7 @@ import ( "github.com/tetratelabs/wazero/experimental/opt" "github.com/tetratelabs/wazero/internal/leb128" "github.com/tetratelabs/wazero/internal/testing/binaryencoding" + "github.com/tetratelabs/wazero/internal/testing/nodiff" "github.com/tetratelabs/wazero/internal/wasm" ) @@ -37,7 +38,7 @@ func require_no_diff(binaryPtr uintptr, binarySize int, checkMemory bool, checkL } }() - requireNoDiff(wasmBin, checkMemory, checkLogging, func(err error) { + nodiff.RequireNoDiff(wasmBin, checkMemory, checkLogging, func(err error) { if err != nil { panic(err) } diff --git a/internal/integration_test/fuzz/wazerolib/nodiff_test.go b/internal/integration_test/fuzz/wazerolib/nodiff_test.go index e232edeee9..757e271d84 100644 --- a/internal/integration_test/fuzz/wazerolib/nodiff_test.go +++ b/internal/integration_test/fuzz/wazerolib/nodiff_test.go @@ -4,8 +4,8 @@ import ( "os" "testing" + "github.com/tetratelabs/wazero/internal/testing/nodiff" "github.com/tetratelabs/wazero/internal/testing/require" - "github.com/tetratelabs/wazero/internal/wasm" ) // TestReRunFailedRequireNoDiffCase re-runs the failed case specified by WASM_BINARY_NAME in testdata directory. @@ -17,202 +17,5 @@ func TestReRunFailedRequireNoDiffCase(t *testing.T) { t.Skip(err) } - requireNoDiff(wasmBin, true, true, func(err error) { require.NoError(t, err) }) -} - -func Test_ensureMutableGlobalsMatch(t *testing.T) { - for _, tc := range []struct { - name string - cm, im *wasm.ModuleInstance - expErr string - }{ - { - name: "no globals", - cm: &wasm.ModuleInstance{}, - im: &wasm.ModuleInstance{}, - }, - { - name: "i32 match", - cm: &wasm.ModuleInstance{ - Globals: []*wasm.GlobalInstance{ - {Type: wasm.GlobalType{ValType: wasm.ValueTypeV128}}, - {Val: 10, Type: wasm.GlobalType{Mutable: true, ValType: wasm.ValueTypeI32}}, - }, - }, - im: &wasm.ModuleInstance{ - Globals: []*wasm.GlobalInstance{ - {Type: wasm.GlobalType{ValType: wasm.ValueTypeV128}}, - {Val: 10, Type: wasm.GlobalType{Mutable: true, ValType: wasm.ValueTypeI32}}, - }, - }, - }, - { - name: "i32 match not match", - cm: &wasm.ModuleInstance{ - Globals: []*wasm.GlobalInstance{ - {Type: wasm.GlobalType{ValType: wasm.ValueTypeV128}}, - {Val: 10, Type: wasm.GlobalType{Mutable: true, ValType: wasm.ValueTypeI32}}, - }, - }, - im: &wasm.ModuleInstance{ - Globals: []*wasm.GlobalInstance{ - {Type: wasm.GlobalType{ValType: wasm.ValueTypeV128}}, - {Val: 11, Type: wasm.GlobalType{Mutable: true, ValType: wasm.ValueTypeI32}}, - }, - }, - expErr: `mutable globals mismatch: - [1] i32: 10 != 11`, - }, - { - name: "i64 match", - cm: &wasm.ModuleInstance{ - Globals: []*wasm.GlobalInstance{ - {Type: wasm.GlobalType{ValType: wasm.ValueTypeV128}}, - {Val: 1 << 62, Type: wasm.GlobalType{Mutable: true, ValType: wasm.ValueTypeI64}}, - }, - }, - im: &wasm.ModuleInstance{ - Globals: []*wasm.GlobalInstance{ - {Type: wasm.GlobalType{ValType: wasm.ValueTypeV128}}, - {Val: 1 << 62, Type: wasm.GlobalType{Mutable: true, ValType: wasm.ValueTypeI64}}, - }, - }, - }, - { - name: "i64 match not match", - cm: &wasm.ModuleInstance{ - Globals: []*wasm.GlobalInstance{ - {Type: wasm.GlobalType{ValType: wasm.ValueTypeV128}}, - {Type: wasm.GlobalType{ValType: wasm.ValueTypeV128}}, - {Val: 1 << 62, Type: wasm.GlobalType{Mutable: true, ValType: wasm.ValueTypeI64}}, - }, - }, - im: &wasm.ModuleInstance{ - Globals: []*wasm.GlobalInstance{ - {Type: wasm.GlobalType{ValType: wasm.ValueTypeV128}}, - {Type: wasm.GlobalType{ValType: wasm.ValueTypeV128}}, - {Val: 1 << 63, Type: wasm.GlobalType{Mutable: true, ValType: wasm.ValueTypeI64}}, - }, - }, - expErr: `mutable globals mismatch: - [2] i64: 4611686018427387904 != 9223372036854775808`, - }, - { - name: "f32 match", - cm: &wasm.ModuleInstance{ - Globals: []*wasm.GlobalInstance{ - {Type: wasm.GlobalType{ValType: wasm.ValueTypeV128}}, - {Val: 10, Type: wasm.GlobalType{Mutable: true, ValType: wasm.ValueTypeF32}}, - }, - }, - im: &wasm.ModuleInstance{ - Globals: []*wasm.GlobalInstance{ - {Type: wasm.GlobalType{ValType: wasm.ValueTypeV128}}, - {Val: 10, Type: wasm.GlobalType{Mutable: true, ValType: wasm.ValueTypeF32}}, - }, - }, - }, - { - name: "f32 match not match", - cm: &wasm.ModuleInstance{ - Globals: []*wasm.GlobalInstance{ - {Type: wasm.GlobalType{ValType: wasm.ValueTypeV128}}, - {Val: 10, Type: wasm.GlobalType{Mutable: true, ValType: wasm.ValueTypeF32}}, - }, - }, - im: &wasm.ModuleInstance{ - Globals: []*wasm.GlobalInstance{ - {Type: wasm.GlobalType{ValType: wasm.ValueTypeV128}}, - {Val: 11, Type: wasm.GlobalType{Mutable: true, ValType: wasm.ValueTypeF32}}, - }, - }, - expErr: `mutable globals mismatch: - [1] f32: 10 != 11`, - }, - { - name: "f64 match", - cm: &wasm.ModuleInstance{ - Globals: []*wasm.GlobalInstance{ - {Type: wasm.GlobalType{ValType: wasm.ValueTypeV128}}, - {Val: 1 << 62, Type: wasm.GlobalType{Mutable: true, ValType: wasm.ValueTypeF64}}, - }, - }, - im: &wasm.ModuleInstance{ - Globals: []*wasm.GlobalInstance{ - {Type: wasm.GlobalType{ValType: wasm.ValueTypeV128}}, - {Val: 1 << 62, Type: wasm.GlobalType{Mutable: true, ValType: wasm.ValueTypeF64}}, - }, - }, - }, - { - name: "f64 match not match", - cm: &wasm.ModuleInstance{ - Globals: []*wasm.GlobalInstance{ - {Type: wasm.GlobalType{ValType: wasm.ValueTypeV128}}, - {Type: wasm.GlobalType{ValType: wasm.ValueTypeV128}}, - {Val: 1 << 62, Type: wasm.GlobalType{Mutable: true, ValType: wasm.ValueTypeF64}}, - }, - }, - im: &wasm.ModuleInstance{ - Globals: []*wasm.GlobalInstance{ - {Type: wasm.GlobalType{ValType: wasm.ValueTypeV128}}, - {Type: wasm.GlobalType{ValType: wasm.ValueTypeV128}}, - {Val: 1 << 63, Type: wasm.GlobalType{Mutable: true, ValType: wasm.ValueTypeF64}}, - }, - }, - expErr: `mutable globals mismatch: - [2] f64: 4611686018427387904 != 9223372036854775808`, - }, - - { - name: "v128 match", - cm: &wasm.ModuleInstance{ - Globals: []*wasm.GlobalInstance{ - {Type: wasm.GlobalType{ValType: wasm.ValueTypeV128}}, - {ValHi: 1 << 62, Type: wasm.GlobalType{Mutable: true, ValType: wasm.ValueTypeV128}}, - }, - }, - im: &wasm.ModuleInstance{ - Globals: []*wasm.GlobalInstance{ - {Type: wasm.GlobalType{ValType: wasm.ValueTypeV128}}, - {ValHi: 1 << 62, Type: wasm.GlobalType{Mutable: true, ValType: wasm.ValueTypeV128}}, - }, - }, - }, - { - name: "v128 match not match", - cm: &wasm.ModuleInstance{ - Globals: []*wasm.GlobalInstance{ - {Type: wasm.GlobalType{ValType: wasm.ValueTypeV128}}, - {Type: wasm.GlobalType{ValType: wasm.ValueTypeV128}}, - {Val: 1 << 62, Type: wasm.GlobalType{Mutable: true, ValType: wasm.ValueTypeV128}}, - }, - }, - im: &wasm.ModuleInstance{ - Globals: []*wasm.GlobalInstance{ - {Type: wasm.GlobalType{ValType: wasm.ValueTypeV128}}, - {Type: wasm.GlobalType{ValType: wasm.ValueTypeV128}}, - {Val: 1 << 62, ValHi: 1234, Type: wasm.GlobalType{Mutable: true, ValType: wasm.ValueTypeV128}}, - }, - }, - expErr: `mutable globals mismatch: - [2] v128: (4611686018427387904,0) != (4611686018427387904,1234)`, - }, - } { - t.Run(tc.name, func(t *testing.T) { - var actualErr error - - // Append the "fuel" inserted by the fuzzer, which will be ignored by ensureMutableGlobalsMatch. - tc.im.Globals = append(tc.im.Globals, &wasm.GlobalInstance{Type: wasm.GlobalType{Mutable: true, ValType: wasm.ValueTypeI32}, Val: 10000}) - tc.cm.Globals = append(tc.cm.Globals, &wasm.GlobalInstance{Type: wasm.GlobalType{Mutable: true, ValType: wasm.ValueTypeI32}, Val: 1}) - ensureMutableGlobalsMatch(tc.cm, tc.im, func(err error) { - actualErr = err - }) - if tc.expErr == "" { - require.NoError(t, actualErr) - } else { - require.Equal(t, tc.expErr, actualErr.Error()) - } - }) - } + nodiff.RequireNoDiff(wasmBin, true, true, func(err error) { require.NoError(t, err) }) } diff --git a/internal/integration_test/fuzzcases/fuzzcases_test.go b/internal/integration_test/fuzzcases/fuzzcases_test.go index 1ece0abf53..39925dad0f 100644 --- a/internal/integration_test/fuzzcases/fuzzcases_test.go +++ b/internal/integration_test/fuzzcases/fuzzcases_test.go @@ -13,6 +13,7 @@ import ( "github.com/tetratelabs/wazero/experimental/opt" "github.com/tetratelabs/wazero/internal/platform" "github.com/tetratelabs/wazero/internal/testing/binaryencoding" + "github.com/tetratelabs/wazero/internal/testing/nodiff" "github.com/tetratelabs/wazero/internal/testing/require" "github.com/tetratelabs/wazero/internal/wasm" ) @@ -1003,3 +1004,10 @@ func Test2070(t *testing.T) { require.NoError(t, err) }) } + +func Test2078(t *testing.T) { + if !platform.CompilerSupported() { + return + } + nodiff.RequireNoDiffT(t, getWasmBinary(t, "2078"), true, true) +} diff --git a/internal/integration_test/fuzzcases/testdata/2078.wasm b/internal/integration_test/fuzzcases/testdata/2078.wasm new file mode 100644 index 0000000000000000000000000000000000000000..7dd5c3a8a14a590b005ae32d7997628c623d3cd1 GIT binary patch literal 42 vcmZQbEY4+QU|?WmV@zPGt7BkhVq{=v0f}(&G4e1tGO#!>a62;cGH?R`WxxZ< literal 0 HcmV?d00001 diff --git a/internal/integration_test/fuzzcases/testdata/2078.wat b/internal/integration_test/fuzzcases/testdata/2078.wat new file mode 100644 index 0000000000..b2493be6ee --- /dev/null +++ b/internal/integration_test/fuzzcases/testdata/2078.wat @@ -0,0 +1,12 @@ +(module + (type (;0;) (func (param i64 i64))) + (func (;0;) (type 0) (param i64 i64) + i32.const 0 + if ;; label = @1 + unreachable + end + i32.const 1 + br_if 0 (;@0;) + ) + (export "" (func 0)) +) diff --git a/internal/integration_test/fuzz/wazerolib/nodiff.go b/internal/testing/nodiff/nodiff.go similarity index 97% rename from internal/integration_test/fuzz/wazerolib/nodiff.go rename to internal/testing/nodiff/nodiff.go index 2afab74a77..5f65fad9b7 100644 --- a/internal/integration_test/fuzz/wazerolib/nodiff.go +++ b/internal/testing/nodiff/nodiff.go @@ -1,4 +1,4 @@ -package main +package nodiff import ( "bytes" @@ -7,6 +7,7 @@ import ( "fmt" "sort" "strings" + "testing" "unsafe" "github.com/tetratelabs/wazero" @@ -15,6 +16,7 @@ import ( "github.com/tetratelabs/wazero/experimental/logging" "github.com/tetratelabs/wazero/experimental/opt" "github.com/tetratelabs/wazero/internal/testing/binaryencoding" + "github.com/tetratelabs/wazero/internal/testing/require" "github.com/tetratelabs/wazero/internal/wasm" ) @@ -42,8 +44,13 @@ func extractInternalWasmModuleFromCompiledModule(c wazero.CompiledModule) (*wasm return cm.module, nil } -// requireNoDiff ensures that the behavior is the same between the compiler and the interpreter for any given binary. -func requireNoDiff(wasmBin []byte, checkMemory, loggingCheck bool, requireNoError func(err error)) { +// RequireNoDiffT is a wrapper of RequireNoDiff for testing.T. +func RequireNoDiffT(t *testing.T, wasmBin []byte, checkMemory, loggingCheck bool) { + RequireNoDiff(wasmBin, checkMemory, loggingCheck, func(err error) { require.NoError(t, err) }) +} + +// RequireNoDiff ensures that the behavior is the same between the compiler and the interpreter for any given binary. +func RequireNoDiff(wasmBin []byte, checkMemory, loggingCheck bool, requireNoError func(err error)) { const features = api.CoreFeaturesV2 | experimental.CoreFeaturesThreads compiler := wazero.NewRuntimeWithConfig(context.Background(), opt.NewRuntimeConfigOptimizingCompiler().WithCoreFeatures(features)) interpreter := wazero.NewRuntimeWithConfig(context.Background(), wazero.NewRuntimeConfigInterpreter().WithCoreFeatures(features)) diff --git a/internal/testing/nodiff/nodiff_test.go b/internal/testing/nodiff/nodiff_test.go new file mode 100644 index 0000000000..b348654c61 --- /dev/null +++ b/internal/testing/nodiff/nodiff_test.go @@ -0,0 +1,205 @@ +package nodiff + +import ( + "testing" + + "github.com/tetratelabs/wazero/internal/testing/require" + "github.com/tetratelabs/wazero/internal/wasm" +) + +func Test_ensureMutableGlobalsMatch(t *testing.T) { + for _, tc := range []struct { + name string + cm, im *wasm.ModuleInstance + expErr string + }{ + { + name: "no globals", + cm: &wasm.ModuleInstance{}, + im: &wasm.ModuleInstance{}, + }, + { + name: "i32 match", + cm: &wasm.ModuleInstance{ + Globals: []*wasm.GlobalInstance{ + {Type: wasm.GlobalType{ValType: wasm.ValueTypeV128}}, + {Val: 10, Type: wasm.GlobalType{Mutable: true, ValType: wasm.ValueTypeI32}}, + }, + }, + im: &wasm.ModuleInstance{ + Globals: []*wasm.GlobalInstance{ + {Type: wasm.GlobalType{ValType: wasm.ValueTypeV128}}, + {Val: 10, Type: wasm.GlobalType{Mutable: true, ValType: wasm.ValueTypeI32}}, + }, + }, + }, + { + name: "i32 match not match", + cm: &wasm.ModuleInstance{ + Globals: []*wasm.GlobalInstance{ + {Type: wasm.GlobalType{ValType: wasm.ValueTypeV128}}, + {Val: 10, Type: wasm.GlobalType{Mutable: true, ValType: wasm.ValueTypeI32}}, + }, + }, + im: &wasm.ModuleInstance{ + Globals: []*wasm.GlobalInstance{ + {Type: wasm.GlobalType{ValType: wasm.ValueTypeV128}}, + {Val: 11, Type: wasm.GlobalType{Mutable: true, ValType: wasm.ValueTypeI32}}, + }, + }, + expErr: `mutable globals mismatch: + [1] i32: 10 != 11`, + }, + { + name: "i64 match", + cm: &wasm.ModuleInstance{ + Globals: []*wasm.GlobalInstance{ + {Type: wasm.GlobalType{ValType: wasm.ValueTypeV128}}, + {Val: 1 << 62, Type: wasm.GlobalType{Mutable: true, ValType: wasm.ValueTypeI64}}, + }, + }, + im: &wasm.ModuleInstance{ + Globals: []*wasm.GlobalInstance{ + {Type: wasm.GlobalType{ValType: wasm.ValueTypeV128}}, + {Val: 1 << 62, Type: wasm.GlobalType{Mutable: true, ValType: wasm.ValueTypeI64}}, + }, + }, + }, + { + name: "i64 match not match", + cm: &wasm.ModuleInstance{ + Globals: []*wasm.GlobalInstance{ + {Type: wasm.GlobalType{ValType: wasm.ValueTypeV128}}, + {Type: wasm.GlobalType{ValType: wasm.ValueTypeV128}}, + {Val: 1 << 62, Type: wasm.GlobalType{Mutable: true, ValType: wasm.ValueTypeI64}}, + }, + }, + im: &wasm.ModuleInstance{ + Globals: []*wasm.GlobalInstance{ + {Type: wasm.GlobalType{ValType: wasm.ValueTypeV128}}, + {Type: wasm.GlobalType{ValType: wasm.ValueTypeV128}}, + {Val: 1 << 63, Type: wasm.GlobalType{Mutable: true, ValType: wasm.ValueTypeI64}}, + }, + }, + expErr: `mutable globals mismatch: + [2] i64: 4611686018427387904 != 9223372036854775808`, + }, + { + name: "f32 match", + cm: &wasm.ModuleInstance{ + Globals: []*wasm.GlobalInstance{ + {Type: wasm.GlobalType{ValType: wasm.ValueTypeV128}}, + {Val: 10, Type: wasm.GlobalType{Mutable: true, ValType: wasm.ValueTypeF32}}, + }, + }, + im: &wasm.ModuleInstance{ + Globals: []*wasm.GlobalInstance{ + {Type: wasm.GlobalType{ValType: wasm.ValueTypeV128}}, + {Val: 10, Type: wasm.GlobalType{Mutable: true, ValType: wasm.ValueTypeF32}}, + }, + }, + }, + { + name: "f32 match not match", + cm: &wasm.ModuleInstance{ + Globals: []*wasm.GlobalInstance{ + {Type: wasm.GlobalType{ValType: wasm.ValueTypeV128}}, + {Val: 10, Type: wasm.GlobalType{Mutable: true, ValType: wasm.ValueTypeF32}}, + }, + }, + im: &wasm.ModuleInstance{ + Globals: []*wasm.GlobalInstance{ + {Type: wasm.GlobalType{ValType: wasm.ValueTypeV128}}, + {Val: 11, Type: wasm.GlobalType{Mutable: true, ValType: wasm.ValueTypeF32}}, + }, + }, + expErr: `mutable globals mismatch: + [1] f32: 10 != 11`, + }, + { + name: "f64 match", + cm: &wasm.ModuleInstance{ + Globals: []*wasm.GlobalInstance{ + {Type: wasm.GlobalType{ValType: wasm.ValueTypeV128}}, + {Val: 1 << 62, Type: wasm.GlobalType{Mutable: true, ValType: wasm.ValueTypeF64}}, + }, + }, + im: &wasm.ModuleInstance{ + Globals: []*wasm.GlobalInstance{ + {Type: wasm.GlobalType{ValType: wasm.ValueTypeV128}}, + {Val: 1 << 62, Type: wasm.GlobalType{Mutable: true, ValType: wasm.ValueTypeF64}}, + }, + }, + }, + { + name: "f64 match not match", + cm: &wasm.ModuleInstance{ + Globals: []*wasm.GlobalInstance{ + {Type: wasm.GlobalType{ValType: wasm.ValueTypeV128}}, + {Type: wasm.GlobalType{ValType: wasm.ValueTypeV128}}, + {Val: 1 << 62, Type: wasm.GlobalType{Mutable: true, ValType: wasm.ValueTypeF64}}, + }, + }, + im: &wasm.ModuleInstance{ + Globals: []*wasm.GlobalInstance{ + {Type: wasm.GlobalType{ValType: wasm.ValueTypeV128}}, + {Type: wasm.GlobalType{ValType: wasm.ValueTypeV128}}, + {Val: 1 << 63, Type: wasm.GlobalType{Mutable: true, ValType: wasm.ValueTypeF64}}, + }, + }, + expErr: `mutable globals mismatch: + [2] f64: 4611686018427387904 != 9223372036854775808`, + }, + + { + name: "v128 match", + cm: &wasm.ModuleInstance{ + Globals: []*wasm.GlobalInstance{ + {Type: wasm.GlobalType{ValType: wasm.ValueTypeV128}}, + {ValHi: 1 << 62, Type: wasm.GlobalType{Mutable: true, ValType: wasm.ValueTypeV128}}, + }, + }, + im: &wasm.ModuleInstance{ + Globals: []*wasm.GlobalInstance{ + {Type: wasm.GlobalType{ValType: wasm.ValueTypeV128}}, + {ValHi: 1 << 62, Type: wasm.GlobalType{Mutable: true, ValType: wasm.ValueTypeV128}}, + }, + }, + }, + { + name: "v128 match not match", + cm: &wasm.ModuleInstance{ + Globals: []*wasm.GlobalInstance{ + {Type: wasm.GlobalType{ValType: wasm.ValueTypeV128}}, + {Type: wasm.GlobalType{ValType: wasm.ValueTypeV128}}, + {Val: 1 << 62, Type: wasm.GlobalType{Mutable: true, ValType: wasm.ValueTypeV128}}, + }, + }, + im: &wasm.ModuleInstance{ + Globals: []*wasm.GlobalInstance{ + {Type: wasm.GlobalType{ValType: wasm.ValueTypeV128}}, + {Type: wasm.GlobalType{ValType: wasm.ValueTypeV128}}, + {Val: 1 << 62, ValHi: 1234, Type: wasm.GlobalType{Mutable: true, ValType: wasm.ValueTypeV128}}, + }, + }, + expErr: `mutable globals mismatch: + [2] v128: (4611686018427387904,0) != (4611686018427387904,1234)`, + }, + } { + t.Run(tc.name, func(t *testing.T) { + var actualErr error + + // Append the "fuel" inserted by the fuzzer, which will be ignored by ensureMutableGlobalsMatch. + tc.im.Globals = append(tc.im.Globals, &wasm.GlobalInstance{Type: wasm.GlobalType{Mutable: true, ValType: wasm.ValueTypeI32}, Val: 10000}) + tc.cm.Globals = append(tc.cm.Globals, &wasm.GlobalInstance{Type: wasm.GlobalType{Mutable: true, ValType: wasm.ValueTypeI32}, Val: 1}) + ensureMutableGlobalsMatch(tc.cm, tc.im, func(err error) { + actualErr = err + }) + if tc.expErr == "" { + require.NoError(t, actualErr) + } else { + require.Equal(t, tc.expErr, actualErr.Error()) + } + }) + } +}