fuzz: ensures mutable global match (#1783)

Signed-off-by: Takeshi Yoneda <t.y.mathetake@gmail.com>
This commit is contained in:
Takeshi Yoneda
2023-10-16 08:40:26 +09:00
committed by GitHub
parent eba1b5a4e1
commit 2b8047770f
2 changed files with 221 additions and 0 deletions

View File

@@ -124,6 +124,38 @@ func requireNoDiff(wasmBin []byte, checkMemory bool, requireNoError func(err err
compilerMem.Buffer, interpreterMem.Buffer))
}
}
ensureMutableGlobalsMatch(compilerMod, interpreterMod, requireNoError)
}
}
func ensureMutableGlobalsMatch(compilerMod, interpreterMod api.Module, requireNoError func(err error)) {
ci, ii := compilerMod.(*wasm.ModuleInstance), interpreterMod.(*wasm.ModuleInstance)
for i := range ci.Globals {
cg := ci.Globals[i]
ig := ii.Globals[i]
if !cg.Type.Mutable {
continue
}
var ok bool
switch ig.Type.ValType {
case wasm.ValueTypeI32, wasm.ValueTypeF32:
ok = uint32(cg.Val) == uint32(ig.Val)
case wasm.ValueTypeI64, wasm.ValueTypeF64:
ok = cg.Val == ig.Val
case wasm.ValueTypeV128:
ok = cg.Val == ig.Val && cg.ValHi == ig.ValHi
default:
ok = true // Ignore other types.
}
if !ok {
if ig.Type.ValType == wasm.ValueTypeV128 {
requireNoError(fmt.Errorf("mutable global[%d] value mismatch: (%v,%v) != (%v,%v)", i, cg.Val, cg.ValHi, ig.Val, ig.ValHi))
} else {
requireNoError(fmt.Errorf("mutable global[%d] value mismatch: %v != %v", i, cg.Val, ig.Val))
}
}
}
}

View File

@@ -5,6 +5,7 @@ import (
"testing"
"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.
@@ -18,3 +19,191 @@ func TestReRunFailedRequireNoDiffCase(t *testing.T) {
requireNoDiff(wasmBin, 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 global[1] value mismatch: 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 global[2] value mismatch: 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 global[1] value mismatch: 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 global[2] value mismatch: 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 global[2] value mismatch: (4611686018427387904,0) != (4611686018427387904,1234)",
},
} {
t.Run(tc.name, func(t *testing.T) {
var actualErr error
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())
}
})
}
}