github.com/wasilibs/wazerox@v0.0.0-20240124024944-4923be63ab5f/internal/integration_test/fuzzcases/fuzzcases_test.go (about)

     1  package fuzzcases
     2  
     3  import (
     4  	"context"
     5  	"embed"
     6  	"fmt"
     7  	"math"
     8  	"runtime"
     9  	"testing"
    10  
    11  	wazero "github.com/wasilibs/wazerox"
    12  	"github.com/wasilibs/wazerox/api"
    13  	"github.com/wasilibs/wazerox/experimental/opt"
    14  	"github.com/wasilibs/wazerox/internal/platform"
    15  	"github.com/wasilibs/wazerox/internal/testing/binaryencoding"
    16  	"github.com/wasilibs/wazerox/internal/testing/require"
    17  	"github.com/wasilibs/wazerox/internal/wasm"
    18  )
    19  
    20  var ctx = context.Background()
    21  
    22  // Note: the name of the test is the PR number. It may be followed by a letter
    23  // if the PR includes more than one test (e.g. "1234a", "1234b").
    24  //
    25  //go:embed testdata/*.wasm
    26  var testcases embed.FS
    27  
    28  func getWasmBinary(t *testing.T, testId string) []byte {
    29  	ret, err := testcases.ReadFile(fmt.Sprintf("testdata/%s.wasm", testId))
    30  	require.NoError(t, err)
    31  	return ret
    32  }
    33  
    34  func runWithCompiler(t *testing.T, runner func(t *testing.T, r wazero.Runtime)) {
    35  	if !platform.CompilerSupported() {
    36  		return
    37  	}
    38  	t.Run("compiler", func(t *testing.T) {
    39  		r := wazero.NewRuntimeWithConfig(ctx, wazero.NewRuntimeConfigCompiler())
    40  		defer r.Close(ctx)
    41  		runner(t, r)
    42  	})
    43  }
    44  
    45  func runWithInterpreter(t *testing.T, runner func(t *testing.T, r wazero.Runtime)) {
    46  	t.Run("interpreter", func(t *testing.T) {
    47  		r := wazero.NewRuntimeWithConfig(ctx, wazero.NewRuntimeConfigInterpreter())
    48  		defer r.Close(ctx)
    49  		runner(t, r)
    50  	})
    51  }
    52  
    53  func runWithWazevo(t *testing.T, runner func(t *testing.T, r wazero.Runtime)) {
    54  	t.Run("wazevo", func(t *testing.T) {
    55  		config := opt.NewRuntimeConfigOptimizingCompiler()
    56  		r := wazero.NewRuntimeWithConfig(ctx, config)
    57  		defer r.Close(ctx)
    58  		runner(t, r)
    59  	})
    60  }
    61  
    62  func run(t *testing.T, runner func(t *testing.T, r wazero.Runtime)) {
    63  	runWithInterpreter(t, runner)
    64  	runWithCompiler(t, runner)
    65  	if runtime.GOARCH == "arm64" {
    66  		runWithWazevo(t, runner)
    67  	}
    68  }
    69  
    70  // Test695 requires two functions to exit with "out of bounds memory access" consistently across the implementations.
    71  func Test695(t *testing.T) {
    72  	run(t, func(t *testing.T, r wazero.Runtime) {
    73  		module, err := r.Instantiate(ctx, getWasmBinary(t, "695"))
    74  		require.NoError(t, err)
    75  
    76  		_, err = module.ExportedFunction("i8x16s").Call(ctx)
    77  		require.NotNil(t, err)
    78  		require.Contains(t, err.Error(), "out of bounds memory access")
    79  
    80  		_, err = module.ExportedFunction("i16x8s").Call(ctx)
    81  		require.NotNil(t, err)
    82  		require.Contains(t, err.Error(), "out of bounds memory access")
    83  	})
    84  }
    85  
    86  func Test696(t *testing.T) {
    87  	run(t, func(t *testing.T, r wazero.Runtime) {
    88  		module, err := r.Instantiate(ctx, getWasmBinary(t, "696"))
    89  		require.NoError(t, err)
    90  		for _, tc := range []struct {
    91  			fnName string
    92  			in     uint64
    93  			exp    [2]uint64
    94  		}{
    95  			{fnName: "select", in: 1 << 5, exp: [2]uint64{0xffffffffffffffff, 0xeeeeeeeeeeeeeeee}},
    96  			{fnName: "select", in: 1, exp: [2]uint64{0xffffffffffffffff, 0xeeeeeeeeeeeeeeee}},
    97  			{fnName: "select", in: 0, exp: [2]uint64{0x1111111111111111, 0x2222222222222222}},
    98  			{fnName: "select", in: 0xffffff, exp: [2]uint64{0xffffffffffffffff, 0xeeeeeeeeeeeeeeee}},
    99  			{fnName: "select", in: 0xffff00, exp: [2]uint64{0xffffffffffffffff, 0xeeeeeeeeeeeeeeee}},
   100  			{fnName: "select", in: 0x000000, exp: [2]uint64{0x1111111111111111, 0x2222222222222222}},
   101  			{fnName: "typed select", in: 1, exp: [2]uint64{0xffffffffffffffff, 0xeeeeeeeeeeeeeeee}},
   102  			{fnName: "typed select", in: 0, exp: [2]uint64{0x1111111111111111, 0x2222222222222222}},
   103  		} {
   104  			res, err := module.ExportedFunction(tc.fnName).Call(ctx, tc.in)
   105  			require.NoError(t, err)
   106  			require.Equal(t, tc.exp[:], res)
   107  		}
   108  	})
   109  }
   110  
   111  // Test699 ensures that accessing element instances and data instances works
   112  // without crash even when the access happens in the nested function call.
   113  func Test699(t *testing.T) {
   114  	run(t, func(t *testing.T, r wazero.Runtime) {
   115  		defer r.Close(ctx)
   116  		_, err := r.Instantiate(ctx, getWasmBinary(t, "699"))
   117  		require.NoError(t, err)
   118  	})
   119  }
   120  
   121  // Test701 requires two functions to exit with "out of bounds memory access" consistently across the implementations.
   122  func Test701(t *testing.T) {
   123  	run(t, func(t *testing.T, r wazero.Runtime) {
   124  		module, err := r.Instantiate(ctx, getWasmBinary(t, "701"))
   125  		require.NoError(t, err)
   126  
   127  		_, err = module.ExportedFunction("i32.extend16_s").Call(ctx)
   128  		require.NotNil(t, err)
   129  		require.Contains(t, err.Error(), "out of bounds memory access")
   130  
   131  		_, err = module.ExportedFunction("i32.extend8_s").Call(ctx)
   132  		require.NotNil(t, err)
   133  		require.Contains(t, err.Error(), "out of bounds memory access")
   134  	})
   135  }
   136  
   137  func Test704(t *testing.T) {
   138  	run(t, func(t *testing.T, r wazero.Runtime) {
   139  		_, err := r.Instantiate(ctx, getWasmBinary(t, "704"))
   140  		require.NoError(t, err)
   141  	})
   142  }
   143  
   144  func Test708(t *testing.T) {
   145  	run(t, func(t *testing.T, r wazero.Runtime) {
   146  		_, err := r.Instantiate(ctx, getWasmBinary(t, "708"))
   147  		require.NotNil(t, err)
   148  		require.Contains(t, err.Error(), "out of bounds memory access")
   149  	})
   150  }
   151  
   152  func Test709(t *testing.T) {
   153  	run(t, func(t *testing.T, r wazero.Runtime) {
   154  		mod, err := r.Instantiate(ctx, getWasmBinary(t, "709"))
   155  		require.NoError(t, err)
   156  
   157  		f := mod.ExportedFunction("f64x2.promote_low_f32x4")
   158  		require.NotNil(t, f)
   159  		res, err := f.Call(ctx)
   160  		require.NoError(t, err)
   161  
   162  		require.NotEqual(t, uint64(0), res[0])
   163  		require.NotEqual(t, uint64(0), res[1])
   164  	})
   165  }
   166  
   167  func Test715(t *testing.T) {
   168  	run(t, func(t *testing.T, r wazero.Runtime) {
   169  		mod, err := r.Instantiate(ctx, getWasmBinary(t, "715"))
   170  		require.NoError(t, err)
   171  
   172  		f := mod.ExportedFunction("select on conditional value after table.size")
   173  		require.NotNil(t, f)
   174  		res, err := f.Call(ctx)
   175  		require.NoError(t, err)
   176  
   177  		require.Equal(t, uint64(1), res[0])
   178  	})
   179  }
   180  
   181  func Test716(t *testing.T) {
   182  	run(t, func(t *testing.T, r wazero.Runtime) {
   183  		mod, err := r.Instantiate(ctx, getWasmBinary(t, "716"))
   184  		require.NoError(t, err)
   185  
   186  		f := mod.ExportedFunction("select on ref.func")
   187  		require.NotNil(t, f)
   188  		res, err := f.Call(ctx)
   189  		require.NoError(t, err)
   190  
   191  		require.Equal(t, uint64(1), res[0])
   192  	})
   193  }
   194  
   195  func Test717(t *testing.T) {
   196  	run(t, func(t *testing.T, r wazero.Runtime) {
   197  		mod, err := r.Instantiate(ctx, getWasmBinary(t, "717"))
   198  		require.NoError(t, err)
   199  
   200  		f := mod.ExportedFunction("vectors")
   201  		require.NotNil(t, f)
   202  		res, err := f.Call(ctx)
   203  		require.NoError(t, err)
   204  
   205  		const expectedLen = 35
   206  		require.Equal(t, expectedLen, len(res))
   207  		for i := 0; i < expectedLen; i++ {
   208  			require.Equal(t, uint64(i), res[i])
   209  		}
   210  	})
   211  }
   212  
   213  func Test718(t *testing.T) {
   214  	run(t, func(t *testing.T, r wazero.Runtime) {
   215  		mod, err := r.Instantiate(ctx, getWasmBinary(t, "718"))
   216  		require.NoError(t, err)
   217  
   218  		f := mod.ExportedFunction("v128.load_zero on the ceil")
   219  		require.NotNil(t, f)
   220  		_, err = f.Call(ctx)
   221  		require.NoError(t, err)
   222  	})
   223  }
   224  
   225  func Test719(t *testing.T) {
   226  	run(t, func(t *testing.T, r wazero.Runtime) {
   227  		mod, err := r.Instantiate(ctx, getWasmBinary(t, "719"))
   228  		require.NoError(t, err)
   229  
   230  		f := mod.ExportedFunction("require unreachable")
   231  		require.NotNil(t, f)
   232  		_, err = f.Call(ctx)
   233  		require.Error(t, err)
   234  		require.Contains(t, err.Error(), "wasm error: unreachable\nwasm stack trace:")
   235  	})
   236  }
   237  
   238  func Test720(t *testing.T) {
   239  	run(t, func(t *testing.T, r wazero.Runtime) {
   240  		mod, err := r.Instantiate(ctx, getWasmBinary(t, "720"))
   241  		require.NoError(t, err)
   242  
   243  		f := mod.ExportedFunction("access memory after table.grow")
   244  		require.NotNil(t, f)
   245  		res, err := f.Call(ctx)
   246  		require.NoError(t, err)
   247  		require.Equal(t, uint32(0xffffffff), uint32(res[0]))
   248  	})
   249  }
   250  
   251  func Test721(t *testing.T) {
   252  	run(t, func(t *testing.T, r wazero.Runtime) {
   253  		mod, err := r.Instantiate(ctx, getWasmBinary(t, "721"))
   254  		require.NoError(t, err)
   255  
   256  		f := mod.ExportedFunction("conditional before elem.drop")
   257  		require.NotNil(t, f)
   258  		ret, err := f.Call(ctx)
   259  		require.NoError(t, err)
   260  
   261  		require.Equal(t, uint64(1), ret[0])
   262  	})
   263  }
   264  
   265  func Test722(t *testing.T) {
   266  	run(t, func(t *testing.T, r wazero.Runtime) {
   267  		mod, err := r.Instantiate(ctx, getWasmBinary(t, "722"))
   268  		require.NoError(t, err)
   269  
   270  		f := mod.ExportedFunction("conditional before data.drop")
   271  		require.NotNil(t, f)
   272  		ret, err := f.Call(ctx)
   273  		require.NoError(t, err)
   274  
   275  		require.Equal(t, uint64(1), ret[0])
   276  	})
   277  }
   278  
   279  func Test725(t *testing.T) {
   280  	functions := []string{"i32.load8_s", "i32.load16_s"}
   281  	run(t, func(t *testing.T, r wazero.Runtime) {
   282  		mod, err := r.Instantiate(ctx, getWasmBinary(t, "725"))
   283  		require.NoError(t, err)
   284  
   285  		for _, fn := range functions {
   286  			f := mod.ExportedFunction(fn)
   287  			require.NotNil(t, f)
   288  			_, err := f.Call(ctx)
   289  			require.Error(t, err)
   290  			require.Contains(t, err.Error(), "out of bounds memory")
   291  		}
   292  	})
   293  }
   294  
   295  // Test730 ensures that the vector min/max operations comply with the spec wrt sign bits of zeros:
   296  //
   297  //   - min(0, 0) = 0, min(-0, 0) = -0, min(0, -0) = -0, min(-0, -0) = -0
   298  //   - max(0, 0) = 0, max(-0, 0) =  0, max(0, -0) =  0, max(-0, -0) = -0
   299  func Test730(t *testing.T) {
   300  	tests := []struct {
   301  		name string
   302  		exp  [2]uint64
   303  	}{
   304  		{name: "f32x4.max", exp: [2]uint64{0x80000000 << 32, 0x00000000}},
   305  		{name: "f32x4.min", exp: [2]uint64{0x80000000, 0x80000000<<32 | 0x80000000}},
   306  		{name: "f64x2.max", exp: [2]uint64{0, 0}},
   307  		{name: "f64x2.min", exp: [2]uint64{1 << 63, 1 << 63}},
   308  		{name: "f64x2.max/mix", exp: [2]uint64{0, 1 << 63}},
   309  		{name: "f64x2.min/mix", exp: [2]uint64{1 << 63, 0}},
   310  	}
   311  
   312  	run(t, func(t *testing.T, r wazero.Runtime) {
   313  		mod, err := r.Instantiate(ctx, getWasmBinary(t, "730"))
   314  		require.NoError(t, err)
   315  
   316  		for _, tc := range tests {
   317  			t.Run(tc.name, func(t *testing.T) {
   318  				f := mod.ExportedFunction(tc.name)
   319  				require.NotNil(t, f)
   320  				actual, err := f.Call(ctx)
   321  				require.NoError(t, err)
   322  				require.Equal(t, tc.exp[:], actual)
   323  			})
   324  		}
   325  	})
   326  }
   327  
   328  func Test733(t *testing.T) {
   329  	run(t, func(t *testing.T, r wazero.Runtime) {
   330  		mod, err := r.Instantiate(ctx, getWasmBinary(t, "733"))
   331  		require.NoError(t, err)
   332  
   333  		name := "out of bounds"
   334  		t.Run(name, func(t *testing.T) {
   335  			f := mod.ExportedFunction(name)
   336  			require.NotNil(t, f)
   337  			_, err = f.Call(ctx)
   338  			require.Error(t, err)
   339  			require.Contains(t, err.Error(), "out of bounds memory")
   340  		})
   341  
   342  		name = "store higher offset"
   343  		t.Run(name, func(t *testing.T) {
   344  			if testing.Short() {
   345  				// Note: this case uses large memory space, so can be slow like 1 to 2 seconds even without -race.
   346  				// The reason is that this test requires roughly 2GB of in-Wasm memory.
   347  				t.SkipNow()
   348  			}
   349  			f := mod.ExportedFunction(name)
   350  			require.NotNil(t, f)
   351  			_, err = f.Call(ctx)
   352  			require.NoError(t, err)
   353  
   354  			mem := mod.Memory()
   355  			require.NotNil(t, mem)
   356  
   357  			v, ok := mem.ReadUint64Le(0x80000100)
   358  			require.True(t, ok)
   359  			require.Equal(t, uint64(0xffffffffffffffff), v)
   360  		})
   361  	})
   362  }
   363  
   364  func Test873(t *testing.T) {
   365  	run(t, func(t *testing.T, r wazero.Runtime) {
   366  		_, err := r.Instantiate(ctx, getWasmBinary(t, "873"))
   367  		require.NoError(t, err)
   368  	})
   369  }
   370  
   371  func Test874(t *testing.T) {
   372  	run(t, func(t *testing.T, r wazero.Runtime) {
   373  		_, err := r.Instantiate(ctx, getWasmBinary(t, "874"))
   374  		require.NoError(t, err)
   375  	})
   376  }
   377  
   378  func Test888(t *testing.T) {
   379  	// This tests that importing FuncRef type globals and using it as an initialization of the locally-defined
   380  	// FuncRef global works fine.
   381  	run(t, func(t *testing.T, r wazero.Runtime) {
   382  		imported := binaryencoding.EncodeModule(&wasm.Module{
   383  			MemorySection: &wasm.Memory{Min: 0, Max: 5, IsMaxEncoded: true},
   384  			GlobalSection: []wasm.Global{
   385  				{
   386  					Type: wasm.GlobalType{
   387  						ValType: wasm.ValueTypeFuncref,
   388  						Mutable: false,
   389  					},
   390  					Init: wasm.ConstantExpression{
   391  						Opcode: wasm.OpcodeRefNull,
   392  						Data:   []byte{wasm.ValueTypeFuncref},
   393  					},
   394  				},
   395  			},
   396  			ExportSection: []wasm.Export{
   397  				{Name: "", Type: wasm.ExternTypeGlobal, Index: 0},
   398  				{Name: "s", Type: wasm.ExternTypeMemory, Index: 0},
   399  			},
   400  		})
   401  
   402  		_, err := r.InstantiateWithConfig(ctx, imported, wazero.NewModuleConfig().WithName("host"))
   403  		require.NoError(t, err)
   404  
   405  		_, err = r.InstantiateWithConfig(ctx, getWasmBinary(t, "888"),
   406  			wazero.NewModuleConfig().WithName("test"))
   407  		require.NoError(t, err)
   408  	})
   409  }
   410  
   411  func Test1054(t *testing.T) {
   412  	if !platform.CompilerSupported() {
   413  		return
   414  	}
   415  
   416  	modules := make([]api.Module, 0, 3)
   417  	run(t, func(t *testing.T, r wazero.Runtime) {
   418  		mod, err := r.Instantiate(ctx, getWasmBinary(t, "1054"))
   419  		require.NoError(t, err)
   420  		modules = append(modules, mod)
   421  	})
   422  
   423  	// Checks if the memory state is the same between engines.
   424  	exp := modules[0].Memory().(*wasm.MemoryInstance).Buffer
   425  	for i := 1; i < len(modules); i++ {
   426  		actual := modules[i].Memory().(*wasm.MemoryInstance).Buffer
   427  		require.Equal(t, exp, actual)
   428  	}
   429  }
   430  
   431  // Test1777 tests that br_table with multiple args works fine even if
   432  // there might be phi eliminations.
   433  func Test1777(t *testing.T) {
   434  	if !platform.CompilerSupported() {
   435  		return
   436  	}
   437  
   438  	run(t, func(t *testing.T, r wazero.Runtime) {
   439  		mod, err := r.Instantiate(ctx, getWasmBinary(t, "1777"))
   440  		require.NoError(t, err)
   441  		f := mod.ExportedFunction("")
   442  		require.NotNil(t, f)
   443  		res, err := f.Call(ctx)
   444  		require.NoError(t, err)
   445  		require.Equal(t, []uint64{18446626425965379583, 4607736361554183979}, res)
   446  	})
   447  }
   448  
   449  // Test1792a tests that v128.const i32x4 is not skipped when state is unreachable.
   450  // This test fails at build-time.
   451  func Test1792a(t *testing.T) {
   452  	if !platform.CompilerSupported() {
   453  		return
   454  	}
   455  	run(t, func(t *testing.T, r wazero.Runtime) {
   456  		_, err := r.Instantiate(ctx, getWasmBinary(t, "1792a"))
   457  		require.NoError(t, err)
   458  	})
   459  }
   460  
   461  // Test1792b tests that OpcodeVhighBits (v128.Bitmask) is typed as V128.
   462  // This test fails at build-time.
   463  func Test1792b(t *testing.T) {
   464  	if !platform.CompilerSupported() {
   465  		return
   466  	}
   467  	run(t, func(t *testing.T, r wazero.Runtime) {
   468  		_, err := r.Instantiate(ctx, getWasmBinary(t, "1792b"))
   469  		require.NoError(t, err)
   470  	})
   471  }
   472  
   473  // Test1792c tests that OpcodeVFcmp (f32x4.eq) is typed as V128.
   474  func Test1792c(t *testing.T) {
   475  	if !platform.CompilerSupported() {
   476  		return
   477  	}
   478  	run(t, func(t *testing.T, r wazero.Runtime) {
   479  		mod, err := r.Instantiate(ctx, getWasmBinary(t, "1792c"))
   480  		require.NoError(t, err)
   481  		f := mod.ExportedFunction("")
   482  		require.NotNil(t, f)
   483  		_, err = f.Call(ctx, 0, 0, 0)
   484  		require.NoError(t, err)
   485  		m := mod.(*wasm.ModuleInstance)
   486  		require.Equal(t, uint64(5044022786561933312), m.Globals[0].Val)
   487  		require.Equal(t, uint64(9205357640488583168), m.Globals[0].ValHi)
   488  	})
   489  }
   490  
   491  // Test1793a tests that OpcodeVAllTrue is lowered to the right registers.
   492  func Test1793a(t *testing.T) {
   493  	if !platform.CompilerSupported() {
   494  		return
   495  	}
   496  	run(t, func(t *testing.T, r wazero.Runtime) {
   497  		mod, err := r.Instantiate(ctx, getWasmBinary(t, "1793a"))
   498  		require.NoError(t, err)
   499  		m := mod.(*wasm.ModuleInstance)
   500  		_, err = m.ExportedFunction("").Call(ctx)
   501  		require.NoError(t, err)
   502  		require.Equal(t, uint64(2531906066518671488), m.Globals[2].Val)
   503  		require.Equal(t, uint64(18446744073709551615), m.Globals[2].ValHi)
   504  	})
   505  }
   506  
   507  // Test1793b tests that OpcodeVIcmp, OpcodeVFcmp are lowered to the right registers.
   508  func Test1793b(t *testing.T) {
   509  	if !platform.CompilerSupported() {
   510  		return
   511  	}
   512  	run(t, func(t *testing.T, r wazero.Runtime) {
   513  		mod, err := r.Instantiate(ctx, getWasmBinary(t, "1793b"))
   514  		require.NoError(t, err)
   515  		m := mod.(*wasm.ModuleInstance)
   516  		_, err = m.ExportedFunction("").Call(ctx, 0, 0, 0, 0)
   517  		require.NoError(t, err)
   518  		require.Equal(t, uint64(18374967954648334335), m.Globals[1].Val)
   519  		require.Equal(t, uint64(18446744073709551615), m.Globals[1].ValHi)
   520  	})
   521  }
   522  
   523  // Test1793c tests that OpcodeVIcmp is lowered to the right registers.
   524  func Test1793c(t *testing.T) {
   525  	if !platform.CompilerSupported() {
   526  		return
   527  	}
   528  	run(t, func(t *testing.T, r wazero.Runtime) {
   529  		mod, err := r.Instantiate(ctx, getWasmBinary(t, "1793c"))
   530  		require.NoError(t, err)
   531  		m := mod.(*wasm.ModuleInstance)
   532  		_, err = m.ExportedFunction("").Call(ctx, 0, 0)
   533  		require.NoError(t, err)
   534  		require.Equal(t, uint64(18446744073709551615), m.Globals[0].Val)
   535  		require.Equal(t, uint64(18446744073709551615), m.Globals[0].ValHi)
   536  	})
   537  }
   538  
   539  // Test1793c tests that OpcodeVShift is lowered to the right registers.
   540  func Test1793d(t *testing.T) {
   541  	if !platform.CompilerSupported() {
   542  		return
   543  	}
   544  	run(t, func(t *testing.T, r wazero.Runtime) {
   545  		mod, err := r.Instantiate(ctx, getWasmBinary(t, "1793d"))
   546  		require.NoError(t, err)
   547  		m := mod.(*wasm.ModuleInstance)
   548  		_, err = m.ExportedFunction("").Call(ctx)
   549  		require.NoError(t, err)
   550  		require.Equal(t, uint64(0), m.Globals[1].Val)
   551  	})
   552  }
   553  
   554  // Test1797a tests that i8x16.shl uses the right register types when lowered.
   555  func Test1797a(t *testing.T) {
   556  	if !platform.CompilerSupported() {
   557  		return
   558  	}
   559  	run(t, func(t *testing.T, r wazero.Runtime) {
   560  		mod, err := r.Instantiate(ctx, getWasmBinary(t, "1797a"))
   561  		require.NoError(t, err)
   562  		m := mod.(*wasm.ModuleInstance)
   563  		res, err := m.ExportedFunction("").Call(ctx)
   564  		require.NoError(t, err)
   565  		require.Equal(t, uint64(0), res[0])
   566  	})
   567  }
   568  
   569  // Test1797a tests that i16x8.shr_u uses the right register types when lowered.
   570  func Test1797b(t *testing.T) {
   571  	if !platform.CompilerSupported() {
   572  		return
   573  	}
   574  	run(t, func(t *testing.T, r wazero.Runtime) {
   575  		mod, err := r.Instantiate(ctx, getWasmBinary(t, "1797b"))
   576  		require.NoError(t, err)
   577  		m := mod.(*wasm.ModuleInstance)
   578  		_, err = m.ExportedFunction("\x00\x00\x00\x00\x00").Call(ctx, 0, 0, 0, 0, 0, 0)
   579  		require.NoError(t, err)
   580  		require.Equal(t, uint64(2666130977255796624), m.Globals[0].Val)
   581  		require.Equal(t, uint64(9223142857682330634), m.Globals[0].ValHi)
   582  	})
   583  }
   584  
   585  // Test1797c tests that the program counter for V128*Shuffle is advanced correctly
   586  // even when an unreachable instruction is present.
   587  func Test1797c(t *testing.T) {
   588  	if !platform.CompilerSupported() {
   589  		return
   590  	}
   591  	run(t, func(t *testing.T, r wazero.Runtime) {
   592  		mod, err := r.Instantiate(ctx, getWasmBinary(t, "1797c"))
   593  		require.NoError(t, err)
   594  		m := mod.(*wasm.ModuleInstance)
   595  		params := make([]uint64, 20)
   596  		_, err = m.ExportedFunction("~zz\x00E1E\x00EE\x00$").Call(ctx, params...)
   597  		require.Error(t, err, "wasm error: unreachable")
   598  	})
   599  }
   600  
   601  // Test1797d tests that the registers are allocated correctly in Vbitselect.
   602  func Test1797d(t *testing.T) {
   603  	if !platform.CompilerSupported() {
   604  		return
   605  	}
   606  	run(t, func(t *testing.T, r wazero.Runtime) {
   607  		mod, err := r.Instantiate(ctx, getWasmBinary(t, "1797d"))
   608  		require.NoError(t, err)
   609  		m := mod.(*wasm.ModuleInstance)
   610  		params := make([]uint64, 20)
   611  		_, err = m.ExportedFunction("p").Call(ctx, params...)
   612  		require.NoError(t, err)
   613  		require.Equal(t, uint64(15092115255309870764), m.Globals[2].Val)
   614  		require.Equal(t, uint64(9241386435284803069), m.Globals[2].ValHi)
   615  	})
   616  }
   617  
   618  // Test1802 tests that load32_splat computes the load from the right offset
   619  // when a nonzero value is on the stack.
   620  func Test1802(t *testing.T) {
   621  	if !platform.CompilerSupported() {
   622  		return
   623  	}
   624  	run(t, func(t *testing.T, r wazero.Runtime) {
   625  		mod, err := r.Instantiate(ctx, getWasmBinary(t, "1802"))
   626  		require.NoError(t, err, "wasm binary should build successfully")
   627  		m := mod.(*wasm.ModuleInstance)
   628  		_, err = m.ExportedFunction("").Call(ctx)
   629  		require.Contains(t, err.Error(), "wasm error: unreachable")
   630  	})
   631  }
   632  
   633  // Test1812 tests that many constant block params work fine.
   634  func Test1812(t *testing.T) {
   635  	if !platform.CompilerSupported() {
   636  		return
   637  	}
   638  	run(t, func(t *testing.T, r wazero.Runtime) {
   639  		mod, err := r.Instantiate(ctx, getWasmBinary(t, "1812"))
   640  		require.NoError(t, err)
   641  		m := mod.(*wasm.ModuleInstance)
   642  		res, err := m.ExportedFunction("").Call(ctx)
   643  		require.NoError(t, err)
   644  		require.Equal(t,
   645  			[]uint64{
   646  				0x8301fd00, 0xfd838783, 0x87878383, 0x9b000087, 0x170001fd,
   647  				0xfd8383fd, 0x87838301, 0x878787, 0x83fd9b00, 0x201fd83, 0x878783,
   648  				0x83fd9b00, 0x9b00fd83, 0xfd8383fd, 0x87838301, 0x87878787,
   649  				0xfd9b0000, 0x87878383, 0x1fd8383,
   650  			}, res)
   651  	})
   652  }
   653  
   654  // Test1817 tests that v128.store uses the right memory layout.
   655  func Test1817(t *testing.T) {
   656  	if !platform.CompilerSupported() {
   657  		return
   658  	}
   659  	run(t, func(t *testing.T, r wazero.Runtime) {
   660  		mod, err := r.Instantiate(ctx, getWasmBinary(t, "1817"))
   661  		require.NoError(t, err)
   662  		m := mod.(*wasm.ModuleInstance)
   663  		_, err = m.ExportedFunction("").Call(ctx)
   664  		require.NoError(t, err)
   665  		buf, ok := m.Memory().Read(15616, 16)
   666  		require.True(t, ok)
   667  		require.Equal(t, []uint8{0, 0, 0, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, buf)
   668  		require.Equal(t, uint64(0x8000000080000000), m.Globals[0].Val)
   669  		require.Equal(t, uint64(0x8000000080000000), m.Globals[0].ValHi)
   670  	})
   671  }
   672  
   673  // Test1820 tests that i16x8.narrow_i32x4_u assigns the dest register correctly.
   674  func Test1820(t *testing.T) {
   675  	if !platform.CompilerSupported() {
   676  		return
   677  	}
   678  	run(t, func(t *testing.T, r wazero.Runtime) {
   679  		mod, err := r.Instantiate(ctx, getWasmBinary(t, "1820"))
   680  		require.NoError(t, err)
   681  		m := mod.(*wasm.ModuleInstance)
   682  		_, err = m.ExportedFunction("").Call(ctx)
   683  		require.NoError(t, err)
   684  		require.Equal(t, uint64(0xFFFFFFFFFFFF0000), m.Globals[1].Val)
   685  		require.Equal(t, uint64(0xFFFF), m.Globals[1].ValHi)
   686  	})
   687  }
   688  
   689  // Test1823 tests that f64x2.pmin lowers to BSL with the right register usage
   690  // (condition register gets overwritten).
   691  func Test1823(t *testing.T) {
   692  	if !platform.CompilerSupported() {
   693  		return
   694  	}
   695  	run(t, func(t *testing.T, r wazero.Runtime) {
   696  		mod, err := r.Instantiate(ctx, getWasmBinary(t, "1823"))
   697  		require.NoError(t, err)
   698  		m := mod.(*wasm.ModuleInstance)
   699  		_, err = m.ExportedFunction("").Call(ctx)
   700  		require.NoError(t, err)
   701  		require.Equal(t, uint64(17282609607625994159), m.Globals[0].Val)
   702  		require.Equal(t, uint64(4671060543367625455), m.Globals[0].ValHi)
   703  	})
   704  }
   705  
   706  // Test1825 tests that OpcodeInsertlane allocates correctly the temporary registers.
   707  func Test1825(t *testing.T) {
   708  	if !platform.CompilerSupported() {
   709  		return
   710  	}
   711  	run(t, func(t *testing.T, r wazero.Runtime) {
   712  		mod, err := r.Instantiate(ctx, getWasmBinary(t, "1825"))
   713  		require.NoError(t, err)
   714  		m := mod.(*wasm.ModuleInstance)
   715  		_, err = m.ExportedFunction("").Call(ctx)
   716  		require.NoError(t, err)
   717  		require.Equal(t, uint64(1099511627775), m.Globals[6].Val)
   718  		require.Equal(t, uint64(18446744073709551615), m.Globals[6].ValHi)
   719  	})
   720  }
   721  
   722  // Test1826 tests that lowerFcopysignImpl allocates correctly the temporary registers.
   723  func Test1826(t *testing.T) {
   724  	if !platform.CompilerSupported() {
   725  		return
   726  	}
   727  	run(t, func(t *testing.T, r wazero.Runtime) {
   728  		mod, err := r.Instantiate(ctx, getWasmBinary(t, "1826"))
   729  		require.NoError(t, err)
   730  		m := mod.(*wasm.ModuleInstance)
   731  		_, err = m.ExportedFunction("3").Call(ctx, 0, 0)
   732  		require.NoError(t, err)
   733  		require.Equal(t, uint64(1608723901141126568), m.Globals[0].Val)
   734  		require.Equal(t, uint64(0), m.Globals[0].ValHi)
   735  	})
   736  }
   737  
   738  func Test1846(t *testing.T) {
   739  	if !platform.CompilerSupported() {
   740  		return
   741  	}
   742  	run(t, func(t *testing.T, r wazero.Runtime) {
   743  		mod, err := r.Instantiate(ctx, getWasmBinary(t, "1846"))
   744  		require.NoError(t, err)
   745  		m := mod.(*wasm.ModuleInstance)
   746  		_, err = m.ExportedFunction("").Call(ctx)
   747  		require.NoError(t, err)
   748  		require.Equal(t, math.Float64bits(2), m.Globals[0].Val)
   749  		require.Equal(t, uint64(0), m.Globals[0].ValHi)
   750  	})
   751  }