Files
wazero/internal/wasm/binary/const_expr_test.go
2023-03-13 12:50:36 +09:00

192 lines
4.1 KiB
Go

package binary
import (
"bytes"
"strconv"
"testing"
"github.com/tetratelabs/wazero/api"
"github.com/tetratelabs/wazero/internal/testing/require"
"github.com/tetratelabs/wazero/internal/wasm"
)
func TestDecodeConstantExpression(t *testing.T) {
tests := []struct {
in []byte
exp wasm.ConstantExpression
}{
{
in: []byte{
wasm.OpcodeRefFunc,
0x80, 0, // Multi byte zero.
wasm.OpcodeEnd,
},
exp: wasm.ConstantExpression{
Opcode: wasm.OpcodeRefFunc,
Data: []byte{0x80, 0},
},
},
{
in: []byte{
wasm.OpcodeRefFunc,
0x80, 0x80, 0x80, 0x4f, // 165675008 in varint encoding.
wasm.OpcodeEnd,
},
exp: wasm.ConstantExpression{
Opcode: wasm.OpcodeRefFunc,
Data: []byte{0x80, 0x80, 0x80, 0x4f},
},
},
{
in: []byte{
wasm.OpcodeRefNull,
wasm.RefTypeFuncref,
wasm.OpcodeEnd,
},
exp: wasm.ConstantExpression{
Opcode: wasm.OpcodeRefNull,
Data: []byte{
wasm.RefTypeFuncref,
},
},
},
{
in: []byte{
wasm.OpcodeRefNull,
wasm.RefTypeExternref,
wasm.OpcodeEnd,
},
exp: wasm.ConstantExpression{
Opcode: wasm.OpcodeRefNull,
Data: []byte{
wasm.RefTypeExternref,
},
},
},
{
in: []byte{
wasm.OpcodeVecPrefix,
wasm.OpcodeVecV128Const,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
wasm.OpcodeEnd,
},
exp: wasm.ConstantExpression{
Opcode: wasm.OpcodeVecV128Const,
Data: []byte{
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
},
},
},
}
for i, tt := range tests {
tc := tt
t.Run(strconv.Itoa(i), func(t *testing.T) {
var actual wasm.ConstantExpression
err := decodeConstantExpression(bytes.NewReader(tc.in),
api.CoreFeatureBulkMemoryOperations|api.CoreFeatureSIMD, &actual)
require.NoError(t, err)
require.Equal(t, tc.exp, actual)
})
}
}
func TestDecodeConstantExpression_errors(t *testing.T) {
tests := []struct {
in []byte
expectedErr string
features api.CoreFeatures
}{
{
in: []byte{
wasm.OpcodeRefFunc,
0,
},
expectedErr: "look for end opcode: EOF",
features: api.CoreFeatureBulkMemoryOperations,
},
{
in: []byte{
wasm.OpcodeRefNull,
},
expectedErr: "read reference type for ref.null: EOF",
features: api.CoreFeatureBulkMemoryOperations,
},
{
in: []byte{
wasm.OpcodeRefNull,
0xff,
wasm.OpcodeEnd,
},
expectedErr: "invalid type for ref.null: 0xff",
features: api.CoreFeatureBulkMemoryOperations,
},
{
in: []byte{
wasm.OpcodeRefNull,
wasm.RefTypeExternref,
wasm.OpcodeEnd,
},
expectedErr: "ref.null is not supported as feature \"bulk-memory-operations\" is disabled",
features: api.CoreFeaturesV1,
},
{
in: []byte{
wasm.OpcodeRefFunc,
0x80, 0,
wasm.OpcodeEnd,
},
expectedErr: "ref.func is not supported as feature \"bulk-memory-operations\" is disabled",
features: api.CoreFeaturesV1,
},
{
in: []byte{
wasm.OpcodeVecPrefix,
wasm.OpcodeVecV128Const,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
wasm.OpcodeEnd,
},
expectedErr: "vector instructions are not supported as feature \"simd\" is disabled",
features: api.CoreFeaturesV1,
},
{
in: []byte{
wasm.OpcodeVecPrefix,
},
expectedErr: "read vector instruction opcode suffix: EOF",
features: api.CoreFeatureSIMD,
},
{
in: []byte{
wasm.OpcodeVecPrefix,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
wasm.OpcodeEnd,
},
expectedErr: "invalid vector opcode for const expression: 0x1",
features: api.CoreFeatureSIMD,
},
{
in: []byte{
wasm.OpcodeVecPrefix,
wasm.OpcodeVecV128Const,
1, 1, 1, 1, 1, 1, 1, 1,
},
expectedErr: "read vector const instruction immediates: needs 16 bytes but was 8 bytes",
features: api.CoreFeatureSIMD,
},
}
for _, tt := range tests {
tc := tt
t.Run(tc.expectedErr, func(t *testing.T) {
var actual wasm.ConstantExpression
err := decodeConstantExpression(bytes.NewReader(tc.in), tc.features, &actual)
require.EqualError(t, err, tc.expectedErr)
})
}
}