1 package wazeroir
2
3 import (
4 "fmt"
5
6 "github.com/tetratelabs/wazero/internal/wasm"
7 )
8
9
10
11 type signature struct {
12 in, out []UnsignedType
13 }
14
15 var (
16 signature_None_None = &signature{}
17 signature_Unknown_None = &signature{
18 in: []UnsignedType{UnsignedTypeUnknown},
19 }
20 signature_None_I32 = &signature{
21 out: []UnsignedType{UnsignedTypeI32},
22 }
23 signature_None_I64 = &signature{
24 out: []UnsignedType{UnsignedTypeI64},
25 }
26 signature_None_V128 = &signature{
27 out: []UnsignedType{UnsignedTypeV128},
28 }
29 signature_None_F32 = &signature{
30 out: []UnsignedType{UnsignedTypeF32},
31 }
32 signature_None_F64 = &signature{
33 out: []UnsignedType{UnsignedTypeF64},
34 }
35 signature_I32_None = &signature{
36 in: []UnsignedType{UnsignedTypeI32},
37 }
38 signature_I64_None = &signature{
39 in: []UnsignedType{UnsignedTypeI64},
40 }
41 signature_F32_None = &signature{
42 in: []UnsignedType{UnsignedTypeF32},
43 }
44 signature_F64_None = &signature{
45 in: []UnsignedType{UnsignedTypeF64},
46 }
47 signature_V128_None = &signature{
48 in: []UnsignedType{UnsignedTypeV128},
49 }
50 signature_I32_I32 = &signature{
51 in: []UnsignedType{UnsignedTypeI32},
52 out: []UnsignedType{UnsignedTypeI32},
53 }
54 signature_I32_I64 = &signature{
55 in: []UnsignedType{UnsignedTypeI32},
56 out: []UnsignedType{UnsignedTypeI64},
57 }
58 signature_I64_I64 = &signature{
59 in: []UnsignedType{UnsignedTypeI64},
60 out: []UnsignedType{UnsignedTypeI64},
61 }
62 signature_I32_F32 = &signature{
63 in: []UnsignedType{UnsignedTypeI32},
64 out: []UnsignedType{UnsignedTypeF32},
65 }
66 signature_I32_F64 = &signature{
67 in: []UnsignedType{UnsignedTypeI32},
68 out: []UnsignedType{UnsignedTypeF64},
69 }
70 signature_I64_I32 = &signature{
71 in: []UnsignedType{UnsignedTypeI64},
72 out: []UnsignedType{UnsignedTypeI32},
73 }
74 signature_I64_F32 = &signature{
75 in: []UnsignedType{UnsignedTypeI64},
76 out: []UnsignedType{UnsignedTypeF32},
77 }
78 signature_I64_F64 = &signature{
79 in: []UnsignedType{UnsignedTypeI64},
80 out: []UnsignedType{UnsignedTypeF64},
81 }
82 signature_F32_I32 = &signature{
83 in: []UnsignedType{UnsignedTypeF32},
84 out: []UnsignedType{UnsignedTypeI32},
85 }
86 signature_F32_I64 = &signature{
87 in: []UnsignedType{UnsignedTypeF32},
88 out: []UnsignedType{UnsignedTypeI64},
89 }
90 signature_F32_F64 = &signature{
91 in: []UnsignedType{UnsignedTypeF32},
92 out: []UnsignedType{UnsignedTypeF64},
93 }
94 signature_F32_F32 = &signature{
95 in: []UnsignedType{UnsignedTypeF32},
96 out: []UnsignedType{UnsignedTypeF32},
97 }
98 signature_F64_I32 = &signature{
99 in: []UnsignedType{UnsignedTypeF64},
100 out: []UnsignedType{UnsignedTypeI32},
101 }
102 signature_F64_F32 = &signature{
103 in: []UnsignedType{UnsignedTypeF64},
104 out: []UnsignedType{UnsignedTypeF32},
105 }
106 signature_F64_I64 = &signature{
107 in: []UnsignedType{UnsignedTypeF64},
108 out: []UnsignedType{UnsignedTypeI64},
109 }
110 signature_F64_F64 = &signature{
111 in: []UnsignedType{UnsignedTypeF64},
112 out: []UnsignedType{UnsignedTypeF64},
113 }
114 signature_I32I32_None = &signature{
115 in: []UnsignedType{UnsignedTypeI32, UnsignedTypeI32},
116 }
117
118 signature_I32I32_I32 = &signature{
119 in: []UnsignedType{UnsignedTypeI32, UnsignedTypeI32},
120 out: []UnsignedType{UnsignedTypeI32},
121 }
122 signature_I32I64_None = &signature{
123 in: []UnsignedType{UnsignedTypeI32, UnsignedTypeI64},
124 }
125 signature_I32F32_None = &signature{
126 in: []UnsignedType{UnsignedTypeI32, UnsignedTypeF32},
127 }
128 signature_I32F64_None = &signature{
129 in: []UnsignedType{UnsignedTypeI32, UnsignedTypeF64},
130 }
131 signature_I64I32_I32 = &signature{
132 in: []UnsignedType{UnsignedTypeI64, UnsignedTypeI32},
133 out: []UnsignedType{UnsignedTypeI32},
134 }
135 signature_I64I64_I32 = &signature{
136 in: []UnsignedType{UnsignedTypeI64, UnsignedTypeI64},
137 out: []UnsignedType{UnsignedTypeI32},
138 }
139 signature_I64I64_I64 = &signature{
140 in: []UnsignedType{UnsignedTypeI64, UnsignedTypeI64},
141 out: []UnsignedType{UnsignedTypeI64},
142 }
143 signature_F32F32_I32 = &signature{
144 in: []UnsignedType{UnsignedTypeF32, UnsignedTypeF32},
145 out: []UnsignedType{UnsignedTypeI32},
146 }
147 signature_F32F32_F32 = &signature{
148 in: []UnsignedType{UnsignedTypeF32, UnsignedTypeF32},
149 out: []UnsignedType{UnsignedTypeF32},
150 }
151 signature_F64F64_I32 = &signature{
152 in: []UnsignedType{UnsignedTypeF64, UnsignedTypeF64},
153 out: []UnsignedType{UnsignedTypeI32},
154 }
155 signature_F64F64_F64 = &signature{
156 in: []UnsignedType{UnsignedTypeF64, UnsignedTypeF64},
157 out: []UnsignedType{UnsignedTypeF64},
158 }
159 signature_I32I32I32_None = &signature{
160 in: []UnsignedType{UnsignedTypeI32, UnsignedTypeI32, UnsignedTypeI32},
161 }
162 signature_I32I64I32_None = &signature{
163 in: []UnsignedType{UnsignedTypeI32, UnsignedTypeI64, UnsignedTypeI32},
164 }
165 signature_UnknownUnknownI32_Unknown = &signature{
166 in: []UnsignedType{UnsignedTypeUnknown, UnsignedTypeUnknown, UnsignedTypeI32},
167 out: []UnsignedType{UnsignedTypeUnknown},
168 }
169 signature_V128V128_V128 = &signature{
170 in: []UnsignedType{UnsignedTypeV128, UnsignedTypeV128},
171 out: []UnsignedType{UnsignedTypeV128},
172 }
173 signature_V128V128V128_V32 = &signature{
174 in: []UnsignedType{UnsignedTypeV128, UnsignedTypeV128, UnsignedTypeV128},
175 out: []UnsignedType{UnsignedTypeV128},
176 }
177 signature_I32_V128 = &signature{
178 in: []UnsignedType{UnsignedTypeI32},
179 out: []UnsignedType{UnsignedTypeV128},
180 }
181 signature_I32V128_None = &signature{
182 in: []UnsignedType{UnsignedTypeI32, UnsignedTypeV128},
183 }
184 signature_I32V128_V128 = &signature{
185 in: []UnsignedType{UnsignedTypeI32, UnsignedTypeV128},
186 out: []UnsignedType{UnsignedTypeV128},
187 }
188 signature_V128I32_V128 = &signature{
189 in: []UnsignedType{UnsignedTypeV128, UnsignedTypeI32},
190 out: []UnsignedType{UnsignedTypeV128},
191 }
192 signature_V128I64_V128 = &signature{
193 in: []UnsignedType{UnsignedTypeV128, UnsignedTypeI64},
194 out: []UnsignedType{UnsignedTypeV128},
195 }
196 signature_V128F32_V128 = &signature{
197 in: []UnsignedType{UnsignedTypeV128, UnsignedTypeF32},
198 out: []UnsignedType{UnsignedTypeV128},
199 }
200 signature_V128F64_V128 = &signature{
201 in: []UnsignedType{UnsignedTypeV128, UnsignedTypeF64},
202 out: []UnsignedType{UnsignedTypeV128},
203 }
204 signature_V128_I32 = &signature{
205 in: []UnsignedType{UnsignedTypeV128},
206 out: []UnsignedType{UnsignedTypeI32},
207 }
208 signature_V128_I64 = &signature{
209 in: []UnsignedType{UnsignedTypeV128},
210 out: []UnsignedType{UnsignedTypeI64},
211 }
212 signature_V128_F32 = &signature{
213 in: []UnsignedType{UnsignedTypeV128},
214 out: []UnsignedType{UnsignedTypeF32},
215 }
216 signature_V128_F64 = &signature{
217 in: []UnsignedType{UnsignedTypeV128},
218 out: []UnsignedType{UnsignedTypeF64},
219 }
220 signature_V128_V128 = &signature{
221 in: []UnsignedType{UnsignedTypeV128},
222 out: []UnsignedType{UnsignedTypeV128},
223 }
224 signature_I64_V128 = &signature{
225 in: []UnsignedType{UnsignedTypeI64},
226 out: []UnsignedType{UnsignedTypeV128},
227 }
228 signature_F32_V128 = &signature{
229 in: []UnsignedType{UnsignedTypeF32},
230 out: []UnsignedType{UnsignedTypeV128},
231 }
232 signature_F64_V128 = &signature{
233 in: []UnsignedType{UnsignedTypeF64},
234 out: []UnsignedType{UnsignedTypeV128},
235 }
236 )
237
238
239
240
241
242
243 func (c *Compiler) wasmOpcodeSignature(op wasm.Opcode, index uint32) (*signature, error) {
244 switch op {
245 case wasm.OpcodeUnreachable, wasm.OpcodeNop, wasm.OpcodeBlock, wasm.OpcodeLoop:
246 return signature_None_None, nil
247 case wasm.OpcodeIf:
248 return signature_I32_None, nil
249 case wasm.OpcodeElse, wasm.OpcodeEnd, wasm.OpcodeBr:
250 return signature_None_None, nil
251 case wasm.OpcodeBrIf, wasm.OpcodeBrTable:
252 return signature_I32_None, nil
253 case wasm.OpcodeReturn:
254 return signature_None_None, nil
255 case wasm.OpcodeCall:
256 return c.funcTypeToSigs.get(c.funcs[index], false ), nil
257 case wasm.OpcodeCallIndirect:
258 return c.funcTypeToSigs.get(index, true ), nil
259 case wasm.OpcodeDrop:
260 return signature_Unknown_None, nil
261 case wasm.OpcodeSelect, wasm.OpcodeTypedSelect:
262 return signature_UnknownUnknownI32_Unknown, nil
263 case wasm.OpcodeLocalGet:
264 inputLen := uint32(len(c.sig.Params))
265 if l := uint32(len(c.localTypes)) + inputLen; index >= l {
266 return nil, fmt.Errorf("invalid local index for local.get %d >= %d", index, l)
267 }
268 var t wasm.ValueType
269 if index < inputLen {
270 t = c.sig.Params[index]
271 } else {
272 t = c.localTypes[index-inputLen]
273 }
274 return wasmValueTypeToUnsignedOutSignature(t), nil
275 case wasm.OpcodeLocalSet:
276 inputLen := uint32(len(c.sig.Params))
277 if l := uint32(len(c.localTypes)) + inputLen; index >= l {
278 return nil, fmt.Errorf("invalid local index for local.get %d >= %d", index, l)
279 }
280 var t wasm.ValueType
281 if index < inputLen {
282 t = c.sig.Params[index]
283 } else {
284 t = c.localTypes[index-inputLen]
285 }
286 return wasmValueTypeToUnsignedInSignature(t), nil
287 case wasm.OpcodeLocalTee:
288 inputLen := uint32(len(c.sig.Params))
289 if l := uint32(len(c.localTypes)) + inputLen; index >= l {
290 return nil, fmt.Errorf("invalid local index for local.get %d >= %d", index, l)
291 }
292 var t wasm.ValueType
293 if index < inputLen {
294 t = c.sig.Params[index]
295 } else {
296 t = c.localTypes[index-inputLen]
297 }
298 return wasmValueTypeToUnsignedInOutSignature(t), nil
299 case wasm.OpcodeGlobalGet:
300 if len(c.globals) <= int(index) {
301 return nil, fmt.Errorf("invalid global index for global.get %d >= %d", index, len(c.globals))
302 }
303 return wasmValueTypeToUnsignedOutSignature(c.globals[index].ValType), nil
304 case wasm.OpcodeGlobalSet:
305 if len(c.globals) <= int(index) {
306 return nil, fmt.Errorf("invalid global index for global.get %d >= %d", index, len(c.globals))
307 }
308 return wasmValueTypeToUnsignedInSignature(c.globals[index].ValType), nil
309 case wasm.OpcodeI32Load:
310 return signature_I32_I32, nil
311 case wasm.OpcodeI64Load:
312 return signature_I32_I64, nil
313 case wasm.OpcodeF32Load:
314 return signature_I32_F32, nil
315 case wasm.OpcodeF64Load:
316 return signature_I32_F64, nil
317 case wasm.OpcodeI32Load8S, wasm.OpcodeI32Load8U, wasm.OpcodeI32Load16S, wasm.OpcodeI32Load16U:
318 return signature_I32_I32, nil
319 case wasm.OpcodeI64Load8S, wasm.OpcodeI64Load8U, wasm.OpcodeI64Load16S, wasm.OpcodeI64Load16U,
320 wasm.OpcodeI64Load32S, wasm.OpcodeI64Load32U:
321 return signature_I32_I64, nil
322 case wasm.OpcodeI32Store:
323 return signature_I32I32_None, nil
324 case wasm.OpcodeI64Store:
325 return signature_I32I64_None, nil
326 case wasm.OpcodeF32Store:
327 return signature_I32F32_None, nil
328 case wasm.OpcodeF64Store:
329 return signature_I32F64_None, nil
330 case wasm.OpcodeI32Store8:
331 return signature_I32I32_None, nil
332 case wasm.OpcodeI32Store16:
333 return signature_I32I32_None, nil
334 case wasm.OpcodeI64Store8:
335 return signature_I32I64_None, nil
336 case wasm.OpcodeI64Store16:
337 return signature_I32I64_None, nil
338 case wasm.OpcodeI64Store32:
339 return signature_I32I64_None, nil
340 case wasm.OpcodeMemorySize:
341 return signature_None_I32, nil
342 case wasm.OpcodeMemoryGrow:
343 return signature_I32_I32, nil
344 case wasm.OpcodeI32Const:
345 return signature_None_I32, nil
346 case wasm.OpcodeI64Const:
347 return signature_None_I64, nil
348 case wasm.OpcodeF32Const:
349 return signature_None_F32, nil
350 case wasm.OpcodeF64Const:
351 return signature_None_F64, nil
352 case wasm.OpcodeI32Eqz:
353 return signature_I32_I32, nil
354 case wasm.OpcodeI32Eq, wasm.OpcodeI32Ne, wasm.OpcodeI32LtS,
355 wasm.OpcodeI32LtU, wasm.OpcodeI32GtS, wasm.OpcodeI32GtU,
356 wasm.OpcodeI32LeS, wasm.OpcodeI32LeU, wasm.OpcodeI32GeS,
357 wasm.OpcodeI32GeU:
358 return signature_I32I32_I32, nil
359 case wasm.OpcodeI64Eqz:
360 return signature_I64_I32, nil
361 case wasm.OpcodeI64Eq, wasm.OpcodeI64Ne, wasm.OpcodeI64LtS,
362 wasm.OpcodeI64LtU, wasm.OpcodeI64GtS, wasm.OpcodeI64GtU,
363 wasm.OpcodeI64LeS, wasm.OpcodeI64LeU, wasm.OpcodeI64GeS,
364 wasm.OpcodeI64GeU:
365 return signature_I64I64_I32, nil
366 case wasm.OpcodeF32Eq, wasm.OpcodeF32Ne, wasm.OpcodeF32Lt,
367 wasm.OpcodeF32Gt, wasm.OpcodeF32Le, wasm.OpcodeF32Ge:
368 return signature_F32F32_I32, nil
369 case wasm.OpcodeF64Eq, wasm.OpcodeF64Ne, wasm.OpcodeF64Lt,
370 wasm.OpcodeF64Gt, wasm.OpcodeF64Le, wasm.OpcodeF64Ge:
371 return signature_F64F64_I32, nil
372 case wasm.OpcodeI32Clz, wasm.OpcodeI32Ctz, wasm.OpcodeI32Popcnt:
373 return signature_I32_I32, nil
374 case wasm.OpcodeI32Add, wasm.OpcodeI32Sub, wasm.OpcodeI32Mul,
375 wasm.OpcodeI32DivS, wasm.OpcodeI32DivU, wasm.OpcodeI32RemS,
376 wasm.OpcodeI32RemU, wasm.OpcodeI32And, wasm.OpcodeI32Or,
377 wasm.OpcodeI32Xor, wasm.OpcodeI32Shl, wasm.OpcodeI32ShrS,
378 wasm.OpcodeI32ShrU, wasm.OpcodeI32Rotl, wasm.OpcodeI32Rotr:
379 return signature_I32I32_I32, nil
380 case wasm.OpcodeI64Clz, wasm.OpcodeI64Ctz, wasm.OpcodeI64Popcnt:
381 return signature_I64_I64, nil
382 case wasm.OpcodeI64Add, wasm.OpcodeI64Sub, wasm.OpcodeI64Mul,
383 wasm.OpcodeI64DivS, wasm.OpcodeI64DivU, wasm.OpcodeI64RemS,
384 wasm.OpcodeI64RemU, wasm.OpcodeI64And, wasm.OpcodeI64Or,
385 wasm.OpcodeI64Xor, wasm.OpcodeI64Shl, wasm.OpcodeI64ShrS,
386 wasm.OpcodeI64ShrU, wasm.OpcodeI64Rotl, wasm.OpcodeI64Rotr:
387 return signature_I64I64_I64, nil
388 case wasm.OpcodeF32Abs, wasm.OpcodeF32Neg, wasm.OpcodeF32Ceil,
389 wasm.OpcodeF32Floor, wasm.OpcodeF32Trunc, wasm.OpcodeF32Nearest,
390 wasm.OpcodeF32Sqrt:
391 return signature_F32_F32, nil
392 case wasm.OpcodeF32Add, wasm.OpcodeF32Sub, wasm.OpcodeF32Mul,
393 wasm.OpcodeF32Div, wasm.OpcodeF32Min, wasm.OpcodeF32Max,
394 wasm.OpcodeF32Copysign:
395 return signature_F32F32_F32, nil
396 case wasm.OpcodeF64Abs, wasm.OpcodeF64Neg, wasm.OpcodeF64Ceil,
397 wasm.OpcodeF64Floor, wasm.OpcodeF64Trunc, wasm.OpcodeF64Nearest,
398 wasm.OpcodeF64Sqrt:
399 return signature_F64_F64, nil
400 case wasm.OpcodeF64Add, wasm.OpcodeF64Sub, wasm.OpcodeF64Mul,
401 wasm.OpcodeF64Div, wasm.OpcodeF64Min, wasm.OpcodeF64Max,
402 wasm.OpcodeF64Copysign:
403 return signature_F64F64_F64, nil
404 case wasm.OpcodeI32WrapI64:
405 return signature_I64_I32, nil
406 case wasm.OpcodeI32TruncF32S, wasm.OpcodeI32TruncF32U:
407 return signature_F32_I32, nil
408 case wasm.OpcodeI32TruncF64S, wasm.OpcodeI32TruncF64U:
409 return signature_F64_I32, nil
410 case wasm.OpcodeI64ExtendI32S, wasm.OpcodeI64ExtendI32U:
411 return signature_I32_I64, nil
412 case wasm.OpcodeI64TruncF32S, wasm.OpcodeI64TruncF32U:
413 return signature_F32_I64, nil
414 case wasm.OpcodeI64TruncF64S, wasm.OpcodeI64TruncF64U:
415 return signature_F64_I64, nil
416 case wasm.OpcodeF32ConvertI32S, wasm.OpcodeF32ConvertI32U:
417 return signature_I32_F32, nil
418 case wasm.OpcodeF32ConvertI64S, wasm.OpcodeF32ConvertI64U:
419 return signature_I64_F32, nil
420 case wasm.OpcodeF32DemoteF64:
421 return signature_F64_F32, nil
422 case wasm.OpcodeF64ConvertI32S, wasm.OpcodeF64ConvertI32U:
423 return signature_I32_F64, nil
424 case wasm.OpcodeF64ConvertI64S, wasm.OpcodeF64ConvertI64U:
425 return signature_I64_F64, nil
426 case wasm.OpcodeF64PromoteF32:
427 return signature_F32_F64, nil
428 case wasm.OpcodeI32ReinterpretF32:
429 return signature_F32_I32, nil
430 case wasm.OpcodeI64ReinterpretF64:
431 return signature_F64_I64, nil
432 case wasm.OpcodeF32ReinterpretI32:
433 return signature_I32_F32, nil
434 case wasm.OpcodeF64ReinterpretI64:
435 return signature_I64_F64, nil
436 case wasm.OpcodeI32Extend8S, wasm.OpcodeI32Extend16S:
437 return signature_I32_I32, nil
438 case wasm.OpcodeI64Extend8S, wasm.OpcodeI64Extend16S, wasm.OpcodeI64Extend32S:
439 return signature_I64_I64, nil
440 case wasm.OpcodeTableGet:
441
442 return signature_I32_I64, nil
443 case wasm.OpcodeTableSet:
444
445 return signature_I32I64_None, nil
446 case wasm.OpcodeRefFunc:
447
448 return signature_None_I64, nil
449 case wasm.OpcodeRefIsNull:
450
451 return signature_I64_I32, nil
452 case wasm.OpcodeRefNull:
453
454 return signature_None_I64, nil
455 case wasm.OpcodeMiscPrefix:
456 switch miscOp := c.body[c.pc+1]; miscOp {
457 case wasm.OpcodeMiscI32TruncSatF32S, wasm.OpcodeMiscI32TruncSatF32U:
458 return signature_F32_I32, nil
459 case wasm.OpcodeMiscI32TruncSatF64S, wasm.OpcodeMiscI32TruncSatF64U:
460 return signature_F64_I32, nil
461 case wasm.OpcodeMiscI64TruncSatF32S, wasm.OpcodeMiscI64TruncSatF32U:
462 return signature_F32_I64, nil
463 case wasm.OpcodeMiscI64TruncSatF64S, wasm.OpcodeMiscI64TruncSatF64U:
464 return signature_F64_I64, nil
465 case wasm.OpcodeMiscMemoryInit, wasm.OpcodeMiscMemoryCopy, wasm.OpcodeMiscMemoryFill,
466 wasm.OpcodeMiscTableInit, wasm.OpcodeMiscTableCopy:
467 return signature_I32I32I32_None, nil
468 case wasm.OpcodeMiscDataDrop, wasm.OpcodeMiscElemDrop:
469 return signature_None_None, nil
470 case wasm.OpcodeMiscTableGrow:
471 return signature_I64I32_I32, nil
472 case wasm.OpcodeMiscTableSize:
473 return signature_None_I32, nil
474 case wasm.OpcodeMiscTableFill:
475 return signature_I32I64I32_None, nil
476 default:
477 return nil, fmt.Errorf("unsupported misc instruction in wazeroir: 0x%x", op)
478 }
479 case wasm.OpcodeVecPrefix:
480 switch vecOp := c.body[c.pc+1]; vecOp {
481 case wasm.OpcodeVecV128Const:
482 return signature_None_V128, nil
483 case wasm.OpcodeVecV128Load, wasm.OpcodeVecV128Load8x8s, wasm.OpcodeVecV128Load8x8u,
484 wasm.OpcodeVecV128Load16x4s, wasm.OpcodeVecV128Load16x4u, wasm.OpcodeVecV128Load32x2s,
485 wasm.OpcodeVecV128Load32x2u, wasm.OpcodeVecV128Load8Splat, wasm.OpcodeVecV128Load16Splat,
486 wasm.OpcodeVecV128Load32Splat, wasm.OpcodeVecV128Load64Splat, wasm.OpcodeVecV128Load32zero,
487 wasm.OpcodeVecV128Load64zero:
488 return signature_I32_V128, nil
489 case wasm.OpcodeVecV128Load8Lane, wasm.OpcodeVecV128Load16Lane,
490 wasm.OpcodeVecV128Load32Lane, wasm.OpcodeVecV128Load64Lane:
491 return signature_I32V128_V128, nil
492 case wasm.OpcodeVecV128Store,
493 wasm.OpcodeVecV128Store8Lane,
494 wasm.OpcodeVecV128Store16Lane,
495 wasm.OpcodeVecV128Store32Lane,
496 wasm.OpcodeVecV128Store64Lane:
497 return signature_I32V128_None, nil
498 case wasm.OpcodeVecI8x16ExtractLaneS,
499 wasm.OpcodeVecI8x16ExtractLaneU,
500 wasm.OpcodeVecI16x8ExtractLaneS,
501 wasm.OpcodeVecI16x8ExtractLaneU,
502 wasm.OpcodeVecI32x4ExtractLane:
503 return signature_V128_I32, nil
504 case wasm.OpcodeVecI64x2ExtractLane:
505 return signature_V128_I64, nil
506 case wasm.OpcodeVecF32x4ExtractLane:
507 return signature_V128_F32, nil
508 case wasm.OpcodeVecF64x2ExtractLane:
509 return signature_V128_F64, nil
510 case wasm.OpcodeVecI8x16ReplaceLane, wasm.OpcodeVecI16x8ReplaceLane, wasm.OpcodeVecI32x4ReplaceLane,
511 wasm.OpcodeVecI8x16Shl, wasm.OpcodeVecI8x16ShrS, wasm.OpcodeVecI8x16ShrU,
512 wasm.OpcodeVecI16x8Shl, wasm.OpcodeVecI16x8ShrS, wasm.OpcodeVecI16x8ShrU,
513 wasm.OpcodeVecI32x4Shl, wasm.OpcodeVecI32x4ShrS, wasm.OpcodeVecI32x4ShrU,
514 wasm.OpcodeVecI64x2Shl, wasm.OpcodeVecI64x2ShrS, wasm.OpcodeVecI64x2ShrU:
515 return signature_V128I32_V128, nil
516 case wasm.OpcodeVecI64x2ReplaceLane:
517 return signature_V128I64_V128, nil
518 case wasm.OpcodeVecF32x4ReplaceLane:
519 return signature_V128F32_V128, nil
520 case wasm.OpcodeVecF64x2ReplaceLane:
521 return signature_V128F64_V128, nil
522 case wasm.OpcodeVecI8x16Splat,
523 wasm.OpcodeVecI16x8Splat,
524 wasm.OpcodeVecI32x4Splat:
525 return signature_I32_V128, nil
526 case wasm.OpcodeVecI64x2Splat:
527 return signature_I64_V128, nil
528 case wasm.OpcodeVecF32x4Splat:
529 return signature_F32_V128, nil
530 case wasm.OpcodeVecF64x2Splat:
531 return signature_F64_V128, nil
532 case wasm.OpcodeVecV128i8x16Shuffle, wasm.OpcodeVecI8x16Swizzle, wasm.OpcodeVecV128And, wasm.OpcodeVecV128Or, wasm.OpcodeVecV128Xor, wasm.OpcodeVecV128AndNot:
533 return signature_V128V128_V128, nil
534 case wasm.OpcodeVecI8x16AllTrue, wasm.OpcodeVecI16x8AllTrue, wasm.OpcodeVecI32x4AllTrue, wasm.OpcodeVecI64x2AllTrue,
535 wasm.OpcodeVecV128AnyTrue,
536 wasm.OpcodeVecI8x16BitMask, wasm.OpcodeVecI16x8BitMask, wasm.OpcodeVecI32x4BitMask, wasm.OpcodeVecI64x2BitMask:
537 return signature_V128_I32, nil
538 case wasm.OpcodeVecV128Not, wasm.OpcodeVecI8x16Neg, wasm.OpcodeVecI16x8Neg, wasm.OpcodeVecI32x4Neg, wasm.OpcodeVecI64x2Neg,
539 wasm.OpcodeVecF32x4Neg, wasm.OpcodeVecF64x2Neg, wasm.OpcodeVecF32x4Sqrt, wasm.OpcodeVecF64x2Sqrt,
540 wasm.OpcodeVecI8x16Abs, wasm.OpcodeVecI8x16Popcnt, wasm.OpcodeVecI16x8Abs, wasm.OpcodeVecI32x4Abs, wasm.OpcodeVecI64x2Abs,
541 wasm.OpcodeVecF32x4Abs, wasm.OpcodeVecF64x2Abs,
542 wasm.OpcodeVecF32x4Ceil, wasm.OpcodeVecF32x4Floor, wasm.OpcodeVecF32x4Trunc, wasm.OpcodeVecF32x4Nearest,
543 wasm.OpcodeVecF64x2Ceil, wasm.OpcodeVecF64x2Floor, wasm.OpcodeVecF64x2Trunc, wasm.OpcodeVecF64x2Nearest,
544 wasm.OpcodeVecI16x8ExtendLowI8x16S, wasm.OpcodeVecI16x8ExtendHighI8x16S, wasm.OpcodeVecI16x8ExtendLowI8x16U, wasm.OpcodeVecI16x8ExtendHighI8x16U,
545 wasm.OpcodeVecI32x4ExtendLowI16x8S, wasm.OpcodeVecI32x4ExtendHighI16x8S, wasm.OpcodeVecI32x4ExtendLowI16x8U, wasm.OpcodeVecI32x4ExtendHighI16x8U,
546 wasm.OpcodeVecI64x2ExtendLowI32x4S, wasm.OpcodeVecI64x2ExtendHighI32x4S, wasm.OpcodeVecI64x2ExtendLowI32x4U, wasm.OpcodeVecI64x2ExtendHighI32x4U,
547 wasm.OpcodeVecI16x8ExtaddPairwiseI8x16S, wasm.OpcodeVecI16x8ExtaddPairwiseI8x16U, wasm.OpcodeVecI32x4ExtaddPairwiseI16x8S, wasm.OpcodeVecI32x4ExtaddPairwiseI16x8U,
548 wasm.OpcodeVecF64x2PromoteLowF32x4Zero, wasm.OpcodeVecF32x4DemoteF64x2Zero,
549 wasm.OpcodeVecF32x4ConvertI32x4S, wasm.OpcodeVecF32x4ConvertI32x4U,
550 wasm.OpcodeVecF64x2ConvertLowI32x4S, wasm.OpcodeVecF64x2ConvertLowI32x4U,
551 wasm.OpcodeVecI32x4TruncSatF32x4S, wasm.OpcodeVecI32x4TruncSatF32x4U,
552 wasm.OpcodeVecI32x4TruncSatF64x2SZero, wasm.OpcodeVecI32x4TruncSatF64x2UZero:
553 return signature_V128_V128, nil
554 case wasm.OpcodeVecV128Bitselect:
555 return signature_V128V128V128_V32, nil
556 case wasm.OpcodeVecI8x16Eq, wasm.OpcodeVecI8x16Ne, wasm.OpcodeVecI8x16LtS, wasm.OpcodeVecI8x16LtU, wasm.OpcodeVecI8x16GtS,
557 wasm.OpcodeVecI8x16GtU, wasm.OpcodeVecI8x16LeS, wasm.OpcodeVecI8x16LeU, wasm.OpcodeVecI8x16GeS, wasm.OpcodeVecI8x16GeU,
558 wasm.OpcodeVecI16x8Eq, wasm.OpcodeVecI16x8Ne, wasm.OpcodeVecI16x8LtS, wasm.OpcodeVecI16x8LtU, wasm.OpcodeVecI16x8GtS,
559 wasm.OpcodeVecI16x8GtU, wasm.OpcodeVecI16x8LeS, wasm.OpcodeVecI16x8LeU, wasm.OpcodeVecI16x8GeS, wasm.OpcodeVecI16x8GeU,
560 wasm.OpcodeVecI32x4Eq, wasm.OpcodeVecI32x4Ne, wasm.OpcodeVecI32x4LtS, wasm.OpcodeVecI32x4LtU, wasm.OpcodeVecI32x4GtS,
561 wasm.OpcodeVecI32x4GtU, wasm.OpcodeVecI32x4LeS, wasm.OpcodeVecI32x4LeU, wasm.OpcodeVecI32x4GeS, wasm.OpcodeVecI32x4GeU,
562 wasm.OpcodeVecI64x2Eq, wasm.OpcodeVecI64x2Ne, wasm.OpcodeVecI64x2LtS, wasm.OpcodeVecI64x2GtS, wasm.OpcodeVecI64x2LeS,
563 wasm.OpcodeVecI64x2GeS, wasm.OpcodeVecF32x4Eq, wasm.OpcodeVecF32x4Ne, wasm.OpcodeVecF32x4Lt, wasm.OpcodeVecF32x4Gt,
564 wasm.OpcodeVecF32x4Le, wasm.OpcodeVecF32x4Ge, wasm.OpcodeVecF64x2Eq, wasm.OpcodeVecF64x2Ne, wasm.OpcodeVecF64x2Lt,
565 wasm.OpcodeVecF64x2Gt, wasm.OpcodeVecF64x2Le, wasm.OpcodeVecF64x2Ge,
566 wasm.OpcodeVecI8x16Add, wasm.OpcodeVecI8x16AddSatS, wasm.OpcodeVecI8x16AddSatU, wasm.OpcodeVecI8x16Sub,
567 wasm.OpcodeVecI8x16SubSatS, wasm.OpcodeVecI8x16SubSatU,
568 wasm.OpcodeVecI16x8Add, wasm.OpcodeVecI16x8AddSatS, wasm.OpcodeVecI16x8AddSatU, wasm.OpcodeVecI16x8Sub,
569 wasm.OpcodeVecI16x8SubSatS, wasm.OpcodeVecI16x8SubSatU, wasm.OpcodeVecI16x8Mul,
570 wasm.OpcodeVecI32x4Add, wasm.OpcodeVecI32x4Sub, wasm.OpcodeVecI32x4Mul,
571 wasm.OpcodeVecI64x2Add, wasm.OpcodeVecI64x2Sub, wasm.OpcodeVecI64x2Mul,
572 wasm.OpcodeVecF32x4Add, wasm.OpcodeVecF32x4Sub, wasm.OpcodeVecF32x4Mul, wasm.OpcodeVecF32x4Div,
573 wasm.OpcodeVecF64x2Add, wasm.OpcodeVecF64x2Sub, wasm.OpcodeVecF64x2Mul, wasm.OpcodeVecF64x2Div,
574 wasm.OpcodeVecI8x16MinS, wasm.OpcodeVecI8x16MinU, wasm.OpcodeVecI8x16MaxS, wasm.OpcodeVecI8x16MaxU, wasm.OpcodeVecI8x16AvgrU,
575 wasm.OpcodeVecI16x8MinS, wasm.OpcodeVecI16x8MinU, wasm.OpcodeVecI16x8MaxS, wasm.OpcodeVecI16x8MaxU, wasm.OpcodeVecI16x8AvgrU,
576 wasm.OpcodeVecI32x4MinS, wasm.OpcodeVecI32x4MinU, wasm.OpcodeVecI32x4MaxS, wasm.OpcodeVecI32x4MaxU,
577 wasm.OpcodeVecF32x4Min, wasm.OpcodeVecF32x4Max, wasm.OpcodeVecF64x2Min, wasm.OpcodeVecF64x2Max,
578 wasm.OpcodeVecF32x4Pmin, wasm.OpcodeVecF32x4Pmax, wasm.OpcodeVecF64x2Pmin, wasm.OpcodeVecF64x2Pmax,
579 wasm.OpcodeVecI16x8Q15mulrSatS,
580 wasm.OpcodeVecI16x8ExtMulLowI8x16S, wasm.OpcodeVecI16x8ExtMulHighI8x16S, wasm.OpcodeVecI16x8ExtMulLowI8x16U, wasm.OpcodeVecI16x8ExtMulHighI8x16U,
581 wasm.OpcodeVecI32x4ExtMulLowI16x8S, wasm.OpcodeVecI32x4ExtMulHighI16x8S, wasm.OpcodeVecI32x4ExtMulLowI16x8U, wasm.OpcodeVecI32x4ExtMulHighI16x8U,
582 wasm.OpcodeVecI64x2ExtMulLowI32x4S, wasm.OpcodeVecI64x2ExtMulHighI32x4S, wasm.OpcodeVecI64x2ExtMulLowI32x4U, wasm.OpcodeVecI64x2ExtMulHighI32x4U,
583 wasm.OpcodeVecI32x4DotI16x8S,
584 wasm.OpcodeVecI8x16NarrowI16x8S, wasm.OpcodeVecI8x16NarrowI16x8U, wasm.OpcodeVecI16x8NarrowI32x4S, wasm.OpcodeVecI16x8NarrowI32x4U:
585 return signature_V128V128_V128, nil
586 default:
587 return nil, fmt.Errorf("unsupported vector instruction in wazeroir: %s", wasm.VectorInstructionName(vecOp))
588 }
589 default:
590 return nil, fmt.Errorf("unsupported instruction in wazeroir: 0x%x", op)
591 }
592 }
593
594
595
596 type funcTypeToIRSignatures struct {
597 directCalls []*signature
598 indirectCalls []*signature
599 wasmTypes []wasm.FunctionType
600 }
601
602
603 func (f *funcTypeToIRSignatures) get(typeIndex wasm.Index, indirect bool) *signature {
604 var sig *signature
605 if indirect {
606 sig = f.indirectCalls[typeIndex]
607 } else {
608 sig = f.directCalls[typeIndex]
609 }
610 if sig != nil {
611 return sig
612 }
613
614 tp := &f.wasmTypes[typeIndex]
615 if indirect {
616 sig = &signature{
617 in: make([]UnsignedType, 0, len(tp.Params)+1),
618 out: make([]UnsignedType, 0, len(tp.Results)),
619 }
620 } else {
621 sig = &signature{
622 in: make([]UnsignedType, 0, len(tp.Params)),
623 out: make([]UnsignedType, 0, len(tp.Results)),
624 }
625 }
626
627 for _, vt := range tp.Params {
628 sig.in = append(sig.in, wasmValueTypeToUnsignedType(vt))
629 }
630 for _, vt := range tp.Results {
631 sig.out = append(sig.out, wasmValueTypeToUnsignedType(vt))
632 }
633
634 if indirect {
635 sig.in = append(sig.in, UnsignedTypeI32)
636 f.indirectCalls[typeIndex] = sig
637 } else {
638 f.directCalls[typeIndex] = sig
639 }
640 return sig
641 }
642
643 func wasmValueTypeToUnsignedType(vt wasm.ValueType) UnsignedType {
644 switch vt {
645 case wasm.ValueTypeI32:
646 return UnsignedTypeI32
647 case wasm.ValueTypeI64,
648
649 wasm.ValueTypeExternref, wasm.ValueTypeFuncref:
650 return UnsignedTypeI64
651 case wasm.ValueTypeF32:
652 return UnsignedTypeF32
653 case wasm.ValueTypeF64:
654 return UnsignedTypeF64
655 case wasm.ValueTypeV128:
656 return UnsignedTypeV128
657 }
658 panic("unreachable")
659 }
660
661 func wasmValueTypeToUnsignedOutSignature(vt wasm.ValueType) *signature {
662 switch vt {
663 case wasm.ValueTypeI32:
664 return signature_None_I32
665 case wasm.ValueTypeI64,
666
667 wasm.ValueTypeExternref, wasm.ValueTypeFuncref:
668 return signature_None_I64
669 case wasm.ValueTypeF32:
670 return signature_None_F32
671 case wasm.ValueTypeF64:
672 return signature_None_F64
673 case wasm.ValueTypeV128:
674 return signature_None_V128
675 }
676 panic("unreachable")
677 }
678
679 func wasmValueTypeToUnsignedInSignature(vt wasm.ValueType) *signature {
680 switch vt {
681 case wasm.ValueTypeI32:
682 return signature_I32_None
683 case wasm.ValueTypeI64,
684
685 wasm.ValueTypeExternref, wasm.ValueTypeFuncref:
686 return signature_I64_None
687 case wasm.ValueTypeF32:
688 return signature_F32_None
689 case wasm.ValueTypeF64:
690 return signature_F64_None
691 case wasm.ValueTypeV128:
692 return signature_V128_None
693 }
694 panic("unreachable")
695 }
696
697 func wasmValueTypeToUnsignedInOutSignature(vt wasm.ValueType) *signature {
698 switch vt {
699 case wasm.ValueTypeI32:
700 return signature_I32_I32
701 case wasm.ValueTypeI64,
702
703 wasm.ValueTypeExternref, wasm.ValueTypeFuncref:
704 return signature_I64_I64
705 case wasm.ValueTypeF32:
706 return signature_F32_F32
707 case wasm.ValueTypeF64:
708 return signature_F64_F64
709 case wasm.ValueTypeV128:
710 return signature_V128_V128
711 }
712 panic("unreachable")
713 }
714
View as plain text