1 package binary
2
3 import (
4 "bytes"
5 "strconv"
6 "testing"
7
8 "github.com/tetratelabs/wazero/api"
9 "github.com/tetratelabs/wazero/internal/testing/require"
10 "github.com/tetratelabs/wazero/internal/wasm"
11 )
12
13 func TestDecodeConstantExpression(t *testing.T) {
14 tests := []struct {
15 in []byte
16 exp wasm.ConstantExpression
17 }{
18 {
19 in: []byte{
20 wasm.OpcodeRefFunc,
21 0x80, 0,
22 wasm.OpcodeEnd,
23 },
24 exp: wasm.ConstantExpression{
25 Opcode: wasm.OpcodeRefFunc,
26 Data: []byte{0x80, 0},
27 },
28 },
29 {
30 in: []byte{
31 wasm.OpcodeRefFunc,
32 0x80, 0x80, 0x80, 0x4f,
33 wasm.OpcodeEnd,
34 },
35 exp: wasm.ConstantExpression{
36 Opcode: wasm.OpcodeRefFunc,
37 Data: []byte{0x80, 0x80, 0x80, 0x4f},
38 },
39 },
40 {
41 in: []byte{
42 wasm.OpcodeRefNull,
43 wasm.RefTypeFuncref,
44 wasm.OpcodeEnd,
45 },
46 exp: wasm.ConstantExpression{
47 Opcode: wasm.OpcodeRefNull,
48 Data: []byte{
49 wasm.RefTypeFuncref,
50 },
51 },
52 },
53 {
54 in: []byte{
55 wasm.OpcodeRefNull,
56 wasm.RefTypeExternref,
57 wasm.OpcodeEnd,
58 },
59 exp: wasm.ConstantExpression{
60 Opcode: wasm.OpcodeRefNull,
61 Data: []byte{
62 wasm.RefTypeExternref,
63 },
64 },
65 },
66 {
67 in: []byte{
68 wasm.OpcodeVecPrefix,
69 wasm.OpcodeVecV128Const,
70 1, 1, 1, 1, 1, 1, 1, 1,
71 1, 1, 1, 1, 1, 1, 1, 1,
72 wasm.OpcodeEnd,
73 },
74 exp: wasm.ConstantExpression{
75 Opcode: wasm.OpcodeVecV128Const,
76 Data: []byte{
77 1, 1, 1, 1, 1, 1, 1, 1,
78 1, 1, 1, 1, 1, 1, 1, 1,
79 },
80 },
81 },
82 }
83
84 for i, tt := range tests {
85 tc := tt
86 t.Run(strconv.Itoa(i), func(t *testing.T) {
87 var actual wasm.ConstantExpression
88 err := decodeConstantExpression(bytes.NewReader(tc.in),
89 api.CoreFeatureBulkMemoryOperations|api.CoreFeatureSIMD, &actual)
90 require.NoError(t, err)
91 require.Equal(t, tc.exp, actual)
92 })
93 }
94 }
95
96 func TestDecodeConstantExpression_errors(t *testing.T) {
97 tests := []struct {
98 in []byte
99 expectedErr string
100 features api.CoreFeatures
101 }{
102 {
103 in: []byte{
104 wasm.OpcodeRefFunc,
105 0,
106 },
107 expectedErr: "look for end opcode: EOF",
108 features: api.CoreFeatureBulkMemoryOperations,
109 },
110 {
111 in: []byte{
112 wasm.OpcodeRefNull,
113 },
114 expectedErr: "read reference type for ref.null: EOF",
115 features: api.CoreFeatureBulkMemoryOperations,
116 },
117 {
118 in: []byte{
119 wasm.OpcodeRefNull,
120 0xff,
121 wasm.OpcodeEnd,
122 },
123 expectedErr: "invalid type for ref.null: 0xff",
124 features: api.CoreFeatureBulkMemoryOperations,
125 },
126 {
127 in: []byte{
128 wasm.OpcodeRefNull,
129 wasm.RefTypeExternref,
130 wasm.OpcodeEnd,
131 },
132 expectedErr: "ref.null is not supported as feature \"bulk-memory-operations\" is disabled",
133 features: api.CoreFeaturesV1,
134 },
135 {
136 in: []byte{
137 wasm.OpcodeRefFunc,
138 0x80, 0,
139 wasm.OpcodeEnd,
140 },
141 expectedErr: "ref.func is not supported as feature \"bulk-memory-operations\" is disabled",
142 features: api.CoreFeaturesV1,
143 },
144 {
145 in: []byte{
146 wasm.OpcodeVecPrefix,
147 wasm.OpcodeVecV128Const,
148 1, 1, 1, 1, 1, 1, 1, 1,
149 1, 1, 1, 1, 1, 1, 1, 1,
150 wasm.OpcodeEnd,
151 },
152 expectedErr: "vector instructions are not supported as feature \"simd\" is disabled",
153 features: api.CoreFeaturesV1,
154 },
155 {
156 in: []byte{
157 wasm.OpcodeVecPrefix,
158 },
159 expectedErr: "read vector instruction opcode suffix: EOF",
160 features: api.CoreFeatureSIMD,
161 },
162 {
163 in: []byte{
164 wasm.OpcodeVecPrefix,
165 1, 1, 1, 1, 1, 1, 1, 1,
166 1, 1, 1, 1, 1, 1, 1, 1,
167 wasm.OpcodeEnd,
168 },
169 expectedErr: "invalid vector opcode for const expression: 0x1",
170 features: api.CoreFeatureSIMD,
171 },
172 {
173 in: []byte{
174 wasm.OpcodeVecPrefix,
175 wasm.OpcodeVecV128Const,
176 1, 1, 1, 1, 1, 1, 1, 1,
177 },
178 expectedErr: "read vector const instruction immediates: needs 16 bytes but was 8 bytes",
179 features: api.CoreFeatureSIMD,
180 },
181 }
182
183 for _, tt := range tests {
184 tc := tt
185 t.Run(tc.expectedErr, func(t *testing.T) {
186 var actual wasm.ConstantExpression
187 err := decodeConstantExpression(bytes.NewReader(tc.in), tc.features, &actual)
188 require.EqualError(t, err, tc.expectedErr)
189 })
190 }
191 }
192
View as plain text