golem_wasm_ast/core/
parser.rs

1// Copyright 2024-2025 Golem Cloud
2//
3// Licensed under the Golem Source License v1.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://license.golem.cloud/LICENSE
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use crate::core::*;
16use crate::AstCustomization;
17use std::io::Write;
18use wasmparser::{BinaryReader, Operator, OperatorsReader, Parser, Payload};
19
20impl TryFrom<wasmparser::RefType> for RefType {
21    type Error = String;
22
23    fn try_from(value: wasmparser::RefType) -> Result<Self, Self::Error> {
24        match value {
25            wasmparser::RefType::FUNCREF => Ok(RefType::FuncRef),
26            wasmparser::RefType::EXTERNREF => Ok(RefType::ExternRef),
27            _ => Err("Unsupported reference type: {value:?}".to_string()),
28        }
29    }
30}
31
32impl TryFrom<wasmparser::ValType> for ValType {
33    type Error = String;
34
35    fn try_from(value: wasmparser::ValType) -> Result<Self, Self::Error> {
36        match value {
37            wasmparser::ValType::I32 => Ok(ValType::Num(NumType::I32)),
38            wasmparser::ValType::I64 => Ok(ValType::Num(NumType::I64)),
39            wasmparser::ValType::F32 => Ok(ValType::Num(NumType::F32)),
40            wasmparser::ValType::F64 => Ok(ValType::Num(NumType::F64)),
41            wasmparser::ValType::V128 => Ok(ValType::Vec(VecType::V128)),
42            wasmparser::ValType::Ref(r) => Ok(ValType::Ref(r.try_into()?)),
43        }
44    }
45}
46
47impl TryFrom<&[wasmparser::ValType]> for ResultType {
48    type Error = String;
49
50    fn try_from(value: &[wasmparser::ValType]) -> Result<Self, Self::Error> {
51        let values = value
52            .iter()
53            .map(|v| (*v).try_into())
54            .collect::<Result<Vec<ValType>, Self::Error>>()?;
55        Ok(ResultType { values })
56    }
57}
58
59impl TryFrom<wasmparser::FuncType> for FuncType {
60    type Error = String;
61
62    fn try_from(value: wasmparser::FuncType) -> Result<Self, Self::Error> {
63        let params = value.params().try_into()?;
64        let results = value.results().try_into()?;
65        Ok(FuncType {
66            input: params,
67            output: results,
68        })
69    }
70}
71
72impl TryFrom<wasmparser::TableType> for TableType {
73    type Error = String;
74
75    fn try_from(value: wasmparser::TableType) -> Result<Self, Self::Error> {
76        Ok(TableType {
77            limits: Limits {
78                min: value.initial,
79                max: value.maximum,
80            },
81            elements: value.element_type.try_into()?,
82        })
83    }
84}
85
86impl TryFrom<wasmparser::MemoryType> for MemType {
87    type Error = String;
88
89    fn try_from(value: wasmparser::MemoryType) -> Result<Self, Self::Error> {
90        if value.memory64 {
91            Err("64-bit memories are not supported".to_string())
92        } else {
93            Ok(MemType {
94                limits: Limits {
95                    min: value.initial,
96                    max: value.maximum,
97                },
98            })
99        }
100    }
101}
102
103impl TryFrom<wasmparser::GlobalType> for GlobalType {
104    type Error = String;
105
106    fn try_from(value: wasmparser::GlobalType) -> Result<Self, Self::Error> {
107        Ok(GlobalType {
108            mutability: if value.mutable { Mut::Var } else { Mut::Const },
109            val_type: value.content_type.try_into()?,
110        })
111    }
112}
113
114impl TryFrom<wasmparser::TypeRef> for TypeRef {
115    type Error = String;
116
117    fn try_from(value: wasmparser::TypeRef) -> Result<Self, Self::Error> {
118        match value {
119            wasmparser::TypeRef::Func(func_idx) => Ok(TypeRef::Func(func_idx)),
120            wasmparser::TypeRef::Table(table_type) => Ok(TypeRef::Table(table_type.try_into()?)),
121            wasmparser::TypeRef::Memory(mem_type) => Ok(TypeRef::Mem(mem_type.try_into()?)),
122            wasmparser::TypeRef::Global(global_type) => {
123                Ok(TypeRef::Global(global_type.try_into()?))
124            }
125            wasmparser::TypeRef::Tag(_) => {
126                Err("Exception handling proposal is not supported".to_string())
127            }
128        }
129    }
130}
131
132impl TryFrom<wasmparser::Import<'_>> for Import {
133    type Error = String;
134
135    fn try_from(value: wasmparser::Import) -> Result<Self, Self::Error> {
136        Ok(Import {
137            module: value.module.to_string(),
138            name: value.name.to_string(),
139            desc: value.ty.try_into()?,
140        })
141    }
142}
143
144impl TryFrom<wasmparser::Table<'_>> for Table {
145    type Error = String;
146
147    fn try_from(value: wasmparser::Table) -> Result<Self, Self::Error> {
148        Ok(Table {
149            table_type: value.ty.try_into()?,
150        })
151    }
152}
153
154impl TryFrom<wasmparser::MemoryType> for Mem {
155    type Error = String;
156
157    fn try_from(value: wasmparser::MemoryType) -> Result<Self, Self::Error> {
158        Ok(Mem {
159            mem_type: value.try_into()?,
160        })
161    }
162}
163
164impl<'a> TryFrom<wasmparser::Global<'a>> for Global {
165    type Error = String;
166
167    fn try_from(value: wasmparser::Global<'a>) -> Result<Self, Self::Error> {
168        let op_reader = value.init_expr.get_operators_reader();
169        let init = op_reader.try_into()?;
170        Ok(Global {
171            global_type: value.ty.try_into()?,
172            init,
173        })
174    }
175}
176
177impl TryFrom<wasmparser::BlockType> for BlockType {
178    type Error = String;
179
180    fn try_from(value: wasmparser::BlockType) -> Result<Self, Self::Error> {
181        match value {
182            wasmparser::BlockType::Empty => Ok(BlockType::None),
183            wasmparser::BlockType::Type(val_type) => Ok(BlockType::Value(val_type.try_into()?)),
184            wasmparser::BlockType::FuncType(type_idx) => Ok(BlockType::Index(type_idx)),
185        }
186    }
187}
188
189impl TryFrom<wasmparser::MemArg> for MemArg {
190    type Error = String;
191
192    fn try_from(value: wasmparser::MemArg) -> Result<Self, Self::Error> {
193        if value.offset > (u32::MAX as u64) {
194            Err("64-bit memories are not supported".to_string())
195        } else {
196            Ok(MemArg {
197                offset: value.offset as u32,
198                align: value.align,
199            })
200        }
201    }
202}
203
204impl TryFrom<wasmparser::HeapType> for RefType {
205    type Error = String;
206
207    fn try_from(value: wasmparser::HeapType) -> Result<Self, Self::Error> {
208        if value == wasmparser::HeapType::EXTERN {
209            Ok(RefType::ExternRef)
210        } else if value == wasmparser::HeapType::FUNC {
211            Ok(RefType::FuncRef)
212        } else {
213            Err("GC proposal is not supported".to_string())
214        }
215    }
216}
217
218impl TryFrom<wasmparser::Export<'_>> for Export {
219    type Error = String;
220
221    fn try_from(value: wasmparser::Export) -> Result<Self, Self::Error> {
222        let desc = match value.kind {
223            wasmparser::ExternalKind::Func => Ok(ExportDesc::Func(value.index)),
224            wasmparser::ExternalKind::Table => Ok(ExportDesc::Table(value.index)),
225            wasmparser::ExternalKind::Memory => Ok(ExportDesc::Mem(value.index)),
226            wasmparser::ExternalKind::Global => Ok(ExportDesc::Global(value.index)),
227            wasmparser::ExternalKind::Tag => {
228                Err("Exception handling proposal is not supported".to_string())
229            }
230        }?;
231        Ok(Export {
232            name: value.name.to_string(),
233            desc,
234        })
235    }
236}
237
238impl TryFrom<wasmparser::ElementKind<'_>> for ElemMode {
239    type Error = String;
240
241    fn try_from(value: wasmparser::ElementKind) -> Result<Self, Self::Error> {
242        match value {
243            wasmparser::ElementKind::Passive => Ok(ElemMode::Passive),
244            wasmparser::ElementKind::Active {
245                table_index,
246                offset_expr,
247            } => Ok(ElemMode::Active {
248                table_idx: table_index.unwrap_or(0),
249                offset: offset_expr.get_operators_reader().try_into()?,
250            }),
251            wasmparser::ElementKind::Declared => Ok(ElemMode::Declarative),
252        }
253    }
254}
255
256impl<T: TryFromExprSource> TryFrom<wasmparser::Element<'_>> for Elem<T> {
257    type Error = String;
258
259    fn try_from(value: wasmparser::Element) -> Result<Self, Self::Error> {
260        let r: Result<(RefType, Vec<T>), String> = match value.items {
261            wasmparser::ElementItems::Functions(indices) => {
262                let mut init = Vec::new();
263                for func_idx in indices {
264                    let func_idx = func_idx
265                        .map_err(|e| format!("Error parsing core module element: {e:?}"))?;
266                    let expr_source = RefFuncExprSource::new(func_idx);
267                    init.push(T::try_from(expr_source)?);
268                }
269                Ok((RefType::FuncRef, init))
270            }
271            wasmparser::ElementItems::Expressions(ref_type, exprs) => {
272                let mut init = Vec::new();
273                for expr in exprs {
274                    let expr =
275                        expr.map_err(|e| format!("Error parsing core module element: {e:?}"))?;
276                    let expr_source = OperatorsReaderExprSource::new(expr.get_operators_reader());
277                    let expr: T = T::try_from(expr_source)?;
278                    init.push(expr);
279                }
280                Ok((ref_type.try_into()?, init))
281            }
282        };
283        let (ref_type, init) = r?;
284
285        Ok(Elem {
286            ref_type,
287            mode: value.kind.try_into()?,
288            init,
289        })
290    }
291}
292
293impl<T: TryFromExprSource + Debug + Clone + PartialEq> TryFrom<wasmparser::DataKind<'_>>
294    for DataMode<T>
295{
296    type Error = String;
297
298    fn try_from(value: wasmparser::DataKind) -> Result<Self, Self::Error> {
299        match value {
300            wasmparser::DataKind::Passive => Ok(DataMode::Passive),
301            wasmparser::DataKind::Active {
302                memory_index,
303                offset_expr,
304            } => {
305                let operators_reader =
306                    OperatorsReaderExprSource::new(offset_expr.get_operators_reader());
307                Ok(DataMode::Active {
308                    memory: memory_index,
309                    offset: T::try_from(operators_reader)?,
310                })
311            }
312        }
313    }
314}
315
316impl<T: TryFromExprSource + Debug + Clone + PartialEq> TryFrom<wasmparser::Data<'_>> for Data<T> {
317    type Error = String;
318
319    fn try_from(value: wasmparser::Data) -> Result<Self, Self::Error> {
320        Ok(Data {
321            init: value.data.to_vec(),
322            mode: value.kind.try_into()?,
323        })
324    }
325}
326
327impl<T: TryFromExprSource> TryFrom<wasmparser::FunctionBody<'_>> for FuncCode<T> {
328    type Error = String;
329
330    fn try_from(value: wasmparser::FunctionBody) -> Result<Self, Self::Error> {
331        let mut locals = Vec::new();
332
333        for local_groups in value
334            .get_locals_reader()
335            .map_err(|e| format!("Error parsing core module function body: {e:?}"))?
336        {
337            let (count, val_type) = local_groups
338                .map_err(|e| format!("Error parsing core module function body: {e:?}"))?;
339            let val_type: ValType = val_type.try_into()?;
340            for _ in 0..count {
341                locals.push(val_type.clone());
342            }
343        }
344
345        let expr_source = OperatorsReaderExprSource::new(
346            value
347                .get_operators_reader()
348                .map_err(|e| format!("Error parsing core module function body: {e:?}"))?,
349        );
350        let body: T = T::try_from(expr_source)?;
351
352        Ok(FuncCode { locals, body })
353    }
354}
355
356enum OperatorTarget {
357    TopLevel(Vec<Instr>),
358    Block(BlockType, Vec<Instr>),
359    Loop(BlockType, Vec<Instr>),
360    If(BlockType, Vec<Instr>),
361    Else(BlockType, Vec<Instr>, Vec<Instr>),
362}
363
364impl OperatorTarget {
365    pub fn push(&mut self, instr: Instr) {
366        match self {
367            OperatorTarget::TopLevel(instructions) => instructions.push(instr),
368            OperatorTarget::Block(_, instructions) => instructions.push(instr),
369            OperatorTarget::Loop(_, instructions) => instructions.push(instr),
370            OperatorTarget::If(_, instructions) => instructions.push(instr),
371            OperatorTarget::Else(_, _, instructions) => instructions.push(instr),
372        }
373    }
374}
375
376impl TryFrom<OperatorsReader<'_>> for Expr {
377    type Error = String;
378
379    fn try_from(value: OperatorsReader) -> Result<Self, Self::Error> {
380        let mut stack = vec![OperatorTarget::TopLevel(Vec::new())];
381
382        for op in value {
383            let op = op.map_err(|e| format!("Error parsing core module instruction: {e:?}"))?;
384
385            let instr = match op {
386                Operator::Unreachable => Some(Instr::Unreachable),
387                Operator::Nop => Some(Instr::Nop),
388                Operator::Block { blockty } => {
389                    let block_type = blockty.try_into()?;
390                    stack.push(OperatorTarget::Block(block_type, Vec::new()));
391                    None
392                }
393                Operator::Loop { blockty } => {
394                    let block_type = blockty.try_into()?;
395                    stack.push(OperatorTarget::Loop(block_type, Vec::new()));
396                    None
397                }
398                Operator::If { blockty } => {
399                    let block_type = blockty.try_into()?;
400                    stack.push(OperatorTarget::If(block_type, Vec::new()));
401                    None
402                }
403                Operator::Else => {
404                    match stack.pop() {
405                        Some(OperatorTarget::If(block_type, true_instrs)) => {
406                            stack.push(OperatorTarget::Else(block_type, true_instrs, Vec::new()));
407                        }
408                        _ => {
409                            return Err(
410                                "Else operator must be preceded by an if operator".to_string()
411                            );
412                        }
413                    }
414                    None
415                }
416                Operator::Try { .. } => {
417                    return Err("Exception handling proposal is not supported".to_string());
418                }
419                Operator::Catch { .. } => {
420                    return Err("Exception handling proposal is not supported".to_string());
421                }
422                Operator::Throw { .. } => {
423                    return Err("Exception handling proposal is not supported".to_string());
424                }
425                Operator::Rethrow { .. } => {
426                    return Err("Exception handling proposal is not supported".to_string());
427                }
428                Operator::End => match stack.pop() {
429                    Some(OperatorTarget::Block(block_type, instrs)) => {
430                        Some(Instr::Block(block_type, instrs))
431                    }
432                    Some(OperatorTarget::Loop(block_type, instrs)) => {
433                        Some(Instr::Loop(block_type, instrs))
434                    }
435                    Some(OperatorTarget::If(block_type, true_instrs)) => {
436                        Some(Instr::If(block_type, true_instrs, Vec::new()))
437                    }
438                    Some(OperatorTarget::Else(block_type, true_instrs, false_instrs)) => {
439                        Some(Instr::If(block_type, true_instrs, false_instrs))
440                    }
441                    Some(OperatorTarget::TopLevel(instrs)) => {
442                        stack.push(OperatorTarget::TopLevel(instrs));
443                        None
444                    }
445                    None => {
446                        return Err(
447                            "End operator must be preceded by a block, loop, or if operator"
448                                .to_string(),
449                        );
450                    }
451                },
452                Operator::Br { relative_depth } => Some(Instr::Br(relative_depth)),
453                Operator::BrIf { relative_depth } => Some(Instr::BrIf(relative_depth)),
454                Operator::BrTable { targets } => {
455                    let labels: Vec<LabelIdx> = targets
456                        .targets()
457                        .map(|r| r.map_err(|err| format!("Failed to read brtable labels: {err:?}")))
458                        .collect::<Result<Vec<LabelIdx>, String>>()?;
459                    Some(Instr::BrTable(labels, targets.default()))
460                }
461                Operator::Return => Some(Instr::Return),
462                Operator::Call { function_index } => Some(Instr::Call(function_index)),
463                Operator::CallIndirect {
464                    type_index,
465                    table_index,
466                    ..
467                } => Some(Instr::CallIndirect(table_index, type_index)),
468                Operator::ReturnCall { .. } => {
469                    return Err("Tail call proposal is not supported".to_string());
470                }
471                Operator::ReturnCallIndirect { .. } => {
472                    return Err("Tail call proposal is not supported".to_string());
473                }
474                Operator::Delegate { .. } => {
475                    return Err("Exception handling proposal is not supported".to_string());
476                }
477                Operator::CatchAll => {
478                    return Err("Exception handling proposal is not supported".to_string());
479                }
480                Operator::Drop => Some(Instr::Drop),
481                Operator::Select => Some(Instr::Select(None)),
482                Operator::TypedSelect { ty } => Some(Instr::Select(Some(vec![ty.try_into()?]))),
483                Operator::LocalGet { local_index } => Some(Instr::LocalGet(local_index)),
484                Operator::LocalSet { local_index } => Some(Instr::LocalSet(local_index)),
485                Operator::LocalTee { local_index } => Some(Instr::LocalTee(local_index)),
486                Operator::GlobalGet { global_index } => Some(Instr::GlobalGet(global_index)),
487                Operator::GlobalSet { global_index } => Some(Instr::GlobalSet(global_index)),
488                Operator::I32Load { memarg } => Some(Instr::Load(
489                    NumOrVecType::Num(NumType::I32),
490                    memarg.try_into()?,
491                )),
492                Operator::I64Load { memarg } => Some(Instr::Load(
493                    NumOrVecType::Num(NumType::I64),
494                    memarg.try_into()?,
495                )),
496                Operator::F32Load { memarg } => Some(Instr::Load(
497                    NumOrVecType::Num(NumType::F32),
498                    memarg.try_into()?,
499                )),
500                Operator::F64Load { memarg } => Some(Instr::Load(
501                    NumOrVecType::Num(NumType::F64),
502                    memarg.try_into()?,
503                )),
504                Operator::I32Load8S { memarg } => Some(Instr::Load8(
505                    NumType::I32,
506                    Signedness::Signed,
507                    memarg.try_into()?,
508                )),
509                Operator::I32Load8U { memarg } => Some(Instr::Load8(
510                    NumType::I32,
511                    Signedness::Unsigned,
512                    memarg.try_into()?,
513                )),
514                Operator::I32Load16S { memarg } => Some(Instr::Load16(
515                    NumType::I32,
516                    Signedness::Signed,
517                    memarg.try_into()?,
518                )),
519                Operator::I32Load16U { memarg } => Some(Instr::Load16(
520                    NumType::I32,
521                    Signedness::Unsigned,
522                    memarg.try_into()?,
523                )),
524                Operator::I64Load8S { memarg } => Some(Instr::Load8(
525                    NumType::I64,
526                    Signedness::Signed,
527                    memarg.try_into()?,
528                )),
529                Operator::I64Load8U { memarg } => Some(Instr::Load8(
530                    NumType::I64,
531                    Signedness::Unsigned,
532                    memarg.try_into()?,
533                )),
534                Operator::I64Load16S { memarg } => Some(Instr::Load16(
535                    NumType::I64,
536                    Signedness::Signed,
537                    memarg.try_into()?,
538                )),
539                Operator::I64Load16U { memarg } => Some(Instr::Load16(
540                    NumType::I64,
541                    Signedness::Unsigned,
542                    memarg.try_into()?,
543                )),
544                Operator::I64Load32S { memarg } => {
545                    Some(Instr::Load32(Signedness::Signed, memarg.try_into()?))
546                }
547                Operator::I64Load32U { memarg } => {
548                    Some(Instr::Load32(Signedness::Unsigned, memarg.try_into()?))
549                }
550                Operator::I32Store { memarg } => Some(Instr::Store(
551                    NumOrVecType::Num(NumType::I32),
552                    memarg.try_into()?,
553                )),
554                Operator::I64Store { memarg } => Some(Instr::Store(
555                    NumOrVecType::Num(NumType::I64),
556                    memarg.try_into()?,
557                )),
558                Operator::F32Store { memarg } => Some(Instr::Store(
559                    NumOrVecType::Num(NumType::F32),
560                    memarg.try_into()?,
561                )),
562                Operator::F64Store { memarg } => Some(Instr::Store(
563                    NumOrVecType::Num(NumType::F64),
564                    memarg.try_into()?,
565                )),
566                Operator::I32Store8 { memarg } => {
567                    Some(Instr::Store8(NumType::I32, memarg.try_into()?))
568                }
569                Operator::I32Store16 { memarg } => {
570                    Some(Instr::Store16(NumType::I32, memarg.try_into()?))
571                }
572                Operator::I64Store8 { memarg } => {
573                    Some(Instr::Store8(NumType::I64, memarg.try_into()?))
574                }
575                Operator::I64Store16 { memarg } => {
576                    Some(Instr::Store16(NumType::I64, memarg.try_into()?))
577                }
578                Operator::I64Store32 { memarg } => Some(Instr::Store32(memarg.try_into()?)),
579                Operator::MemorySize { .. } => Some(Instr::MemorySize),
580                Operator::MemoryGrow { .. } => Some(Instr::MemoryGrow),
581                Operator::I32Const { value } => Some(Instr::I32Const(value)),
582                Operator::I64Const { value } => Some(Instr::I64Const(value)),
583                Operator::F32Const { value } => Some(Instr::F32Const(f32::from_bits(value.bits()))),
584                Operator::F64Const { value } => Some(Instr::F64Const(f64::from_bits(value.bits()))),
585                Operator::RefNull { hty } => Some(Instr::RefNull(hty.try_into()?)),
586                Operator::RefIsNull => Some(Instr::RefIsNull),
587                Operator::RefFunc { function_index } => Some(Instr::RefFunc(function_index)),
588                Operator::I32Eqz => Some(Instr::IEqz(IntWidth::I32)),
589                Operator::I32Eq => Some(Instr::IEq(IntWidth::I32)),
590                Operator::I32Ne => Some(Instr::INe(IntWidth::I32)),
591                Operator::I32LtS => Some(Instr::ILt(IntWidth::I32, Signedness::Signed)),
592                Operator::I32LtU => Some(Instr::ILt(IntWidth::I32, Signedness::Unsigned)),
593                Operator::I32GtS => Some(Instr::IGt(IntWidth::I32, Signedness::Signed)),
594                Operator::I32GtU => Some(Instr::IGt(IntWidth::I32, Signedness::Unsigned)),
595                Operator::I32LeS => Some(Instr::ILe(IntWidth::I32, Signedness::Signed)),
596                Operator::I32LeU => Some(Instr::ILe(IntWidth::I32, Signedness::Unsigned)),
597                Operator::I32GeS => Some(Instr::IGe(IntWidth::I32, Signedness::Signed)),
598                Operator::I32GeU => Some(Instr::IGe(IntWidth::I32, Signedness::Unsigned)),
599                Operator::I64Eqz => Some(Instr::IEqz(IntWidth::I64)),
600                Operator::I64Eq => Some(Instr::IEq(IntWidth::I64)),
601                Operator::I64Ne => Some(Instr::INe(IntWidth::I64)),
602                Operator::I64LtS => Some(Instr::ILt(IntWidth::I64, Signedness::Signed)),
603                Operator::I64LtU => Some(Instr::ILt(IntWidth::I64, Signedness::Unsigned)),
604                Operator::I64GtS => Some(Instr::IGt(IntWidth::I64, Signedness::Signed)),
605                Operator::I64GtU => Some(Instr::IGt(IntWidth::I64, Signedness::Unsigned)),
606                Operator::I64LeS => Some(Instr::ILe(IntWidth::I64, Signedness::Signed)),
607                Operator::I64LeU => Some(Instr::ILe(IntWidth::I64, Signedness::Unsigned)),
608                Operator::I64GeS => Some(Instr::IGe(IntWidth::I64, Signedness::Signed)),
609                Operator::I64GeU => Some(Instr::IGe(IntWidth::I64, Signedness::Unsigned)),
610                Operator::F32Eq => Some(Instr::FEq(FloatWidth::F32)),
611                Operator::F32Ne => Some(Instr::FNe(FloatWidth::F32)),
612                Operator::F32Lt => Some(Instr::FLt(FloatWidth::F32)),
613                Operator::F32Gt => Some(Instr::FGt(FloatWidth::F32)),
614                Operator::F32Le => Some(Instr::FLe(FloatWidth::F32)),
615                Operator::F32Ge => Some(Instr::FGe(FloatWidth::F32)),
616                Operator::F64Eq => Some(Instr::FEq(FloatWidth::F64)),
617                Operator::F64Ne => Some(Instr::FNe(FloatWidth::F64)),
618                Operator::F64Lt => Some(Instr::FLt(FloatWidth::F64)),
619                Operator::F64Gt => Some(Instr::FGt(FloatWidth::F64)),
620                Operator::F64Le => Some(Instr::FLe(FloatWidth::F64)),
621                Operator::F64Ge => Some(Instr::FGe(FloatWidth::F64)),
622                Operator::I32Clz => Some(Instr::IClz(IntWidth::I32)),
623                Operator::I32Ctz => Some(Instr::ICtz(IntWidth::I32)),
624                Operator::I32Popcnt => Some(Instr::IPopCnt(IntWidth::I32)),
625                Operator::I32Add => Some(Instr::IAdd(IntWidth::I32)),
626                Operator::I32Sub => Some(Instr::ISub(IntWidth::I32)),
627                Operator::I32Mul => Some(Instr::IMul(IntWidth::I32)),
628                Operator::I32DivS => Some(Instr::IDiv(IntWidth::I32, Signedness::Signed)),
629                Operator::I32DivU => Some(Instr::IDiv(IntWidth::I32, Signedness::Unsigned)),
630                Operator::I32RemS => Some(Instr::IRem(IntWidth::I32, Signedness::Signed)),
631                Operator::I32RemU => Some(Instr::IRem(IntWidth::I32, Signedness::Unsigned)),
632                Operator::I32And => Some(Instr::IAnd(IntWidth::I32)),
633                Operator::I32Or => Some(Instr::IOr(IntWidth::I32)),
634                Operator::I32Xor => Some(Instr::IXor(IntWidth::I32)),
635                Operator::I32Shl => Some(Instr::IShl(IntWidth::I32)),
636                Operator::I32ShrS => Some(Instr::IShr(IntWidth::I32, Signedness::Signed)),
637                Operator::I32ShrU => Some(Instr::IShr(IntWidth::I32, Signedness::Unsigned)),
638                Operator::I32Rotl => Some(Instr::IRotL(IntWidth::I32)),
639                Operator::I32Rotr => Some(Instr::IRotR(IntWidth::I32)),
640                Operator::I64Clz => Some(Instr::IClz(IntWidth::I64)),
641                Operator::I64Ctz => Some(Instr::ICtz(IntWidth::I64)),
642                Operator::I64Popcnt => Some(Instr::IPopCnt(IntWidth::I64)),
643                Operator::I64Add => Some(Instr::IAdd(IntWidth::I64)),
644                Operator::I64Sub => Some(Instr::ISub(IntWidth::I64)),
645                Operator::I64Mul => Some(Instr::IMul(IntWidth::I64)),
646                Operator::I64DivS => Some(Instr::IDiv(IntWidth::I64, Signedness::Signed)),
647                Operator::I64DivU => Some(Instr::IDiv(IntWidth::I64, Signedness::Unsigned)),
648                Operator::I64RemS => Some(Instr::IRem(IntWidth::I64, Signedness::Signed)),
649                Operator::I64RemU => Some(Instr::IRem(IntWidth::I64, Signedness::Unsigned)),
650                Operator::I64And => Some(Instr::IAnd(IntWidth::I64)),
651                Operator::I64Or => Some(Instr::IOr(IntWidth::I64)),
652                Operator::I64Xor => Some(Instr::IXor(IntWidth::I64)),
653                Operator::I64Shl => Some(Instr::IShl(IntWidth::I64)),
654                Operator::I64ShrS => Some(Instr::IShr(IntWidth::I64, Signedness::Signed)),
655                Operator::I64ShrU => Some(Instr::IShr(IntWidth::I64, Signedness::Unsigned)),
656                Operator::I64Rotl => Some(Instr::IRotL(IntWidth::I64)),
657                Operator::I64Rotr => Some(Instr::IRotR(IntWidth::I64)),
658                Operator::F32Abs => Some(Instr::FAbs(FloatWidth::F32)),
659                Operator::F32Neg => Some(Instr::FNeg(FloatWidth::F32)),
660                Operator::F32Ceil => Some(Instr::FCeil(FloatWidth::F32)),
661                Operator::F32Floor => Some(Instr::FFloor(FloatWidth::F32)),
662                Operator::F32Trunc => Some(Instr::FTrunc(FloatWidth::F32)),
663                Operator::F32Nearest => Some(Instr::FNearest(FloatWidth::F32)),
664                Operator::F32Sqrt => Some(Instr::FSqrt(FloatWidth::F32)),
665                Operator::F32Add => Some(Instr::FAdd(FloatWidth::F32)),
666                Operator::F32Sub => Some(Instr::FSub(FloatWidth::F32)),
667                Operator::F32Mul => Some(Instr::FMul(FloatWidth::F32)),
668                Operator::F32Div => Some(Instr::FDiv(FloatWidth::F32)),
669                Operator::F32Min => Some(Instr::FMin(FloatWidth::F32)),
670                Operator::F32Max => Some(Instr::FMax(FloatWidth::F32)),
671                Operator::F32Copysign => Some(Instr::FCopySign(FloatWidth::F32)),
672                Operator::F64Abs => Some(Instr::FAbs(FloatWidth::F64)),
673                Operator::F64Neg => Some(Instr::FNeg(FloatWidth::F64)),
674                Operator::F64Ceil => Some(Instr::FCeil(FloatWidth::F64)),
675                Operator::F64Floor => Some(Instr::FFloor(FloatWidth::F64)),
676                Operator::F64Trunc => Some(Instr::FTrunc(FloatWidth::F64)),
677                Operator::F64Nearest => Some(Instr::FNearest(FloatWidth::F64)),
678                Operator::F64Sqrt => Some(Instr::FSqrt(FloatWidth::F64)),
679                Operator::F64Add => Some(Instr::FAdd(FloatWidth::F64)),
680                Operator::F64Sub => Some(Instr::FSub(FloatWidth::F64)),
681                Operator::F64Mul => Some(Instr::FMul(FloatWidth::F64)),
682                Operator::F64Div => Some(Instr::FDiv(FloatWidth::F64)),
683                Operator::F64Min => Some(Instr::FMin(FloatWidth::F64)),
684                Operator::F64Max => Some(Instr::FMax(FloatWidth::F64)),
685                Operator::F64Copysign => Some(Instr::FCopySign(FloatWidth::F64)),
686                Operator::I32WrapI64 => Some(Instr::I32WrapI64),
687                Operator::I32TruncF32S => Some(Instr::ITruncF(
688                    IntWidth::I32,
689                    FloatWidth::F32,
690                    Signedness::Signed,
691                )),
692                Operator::I32TruncF32U => Some(Instr::ITruncF(
693                    IntWidth::I32,
694                    FloatWidth::F32,
695                    Signedness::Unsigned,
696                )),
697                Operator::I32TruncF64S => Some(Instr::ITruncF(
698                    IntWidth::I32,
699                    FloatWidth::F64,
700                    Signedness::Signed,
701                )),
702                Operator::I32TruncF64U => Some(Instr::ITruncF(
703                    IntWidth::I32,
704                    FloatWidth::F64,
705                    Signedness::Unsigned,
706                )),
707                Operator::I64ExtendI32S => Some(Instr::I64ExtendI32(Signedness::Signed)),
708                Operator::I64ExtendI32U => Some(Instr::I64ExtendI32(Signedness::Unsigned)),
709                Operator::I64TruncF32S => Some(Instr::ITruncF(
710                    IntWidth::I64,
711                    FloatWidth::F32,
712                    Signedness::Signed,
713                )),
714                Operator::I64TruncF32U => Some(Instr::ITruncF(
715                    IntWidth::I64,
716                    FloatWidth::F32,
717                    Signedness::Unsigned,
718                )),
719                Operator::I64TruncF64S => Some(Instr::ITruncF(
720                    IntWidth::I64,
721                    FloatWidth::F64,
722                    Signedness::Signed,
723                )),
724                Operator::I64TruncF64U => Some(Instr::ITruncF(
725                    IntWidth::I64,
726                    FloatWidth::F64,
727                    Signedness::Unsigned,
728                )),
729                Operator::F32ConvertI32S => Some(Instr::FConvertI(
730                    FloatWidth::F32,
731                    IntWidth::I32,
732                    Signedness::Signed,
733                )),
734                Operator::F32ConvertI32U => Some(Instr::FConvertI(
735                    FloatWidth::F32,
736                    IntWidth::I32,
737                    Signedness::Unsigned,
738                )),
739                Operator::F32ConvertI64S => Some(Instr::FConvertI(
740                    FloatWidth::F32,
741                    IntWidth::I64,
742                    Signedness::Signed,
743                )),
744                Operator::F32ConvertI64U => Some(Instr::FConvertI(
745                    FloatWidth::F32,
746                    IntWidth::I64,
747                    Signedness::Unsigned,
748                )),
749                Operator::F32DemoteF64 => Some(Instr::F32DemoteF64),
750                Operator::F64ConvertI32S => Some(Instr::FConvertI(
751                    FloatWidth::F64,
752                    IntWidth::I32,
753                    Signedness::Signed,
754                )),
755                Operator::F64ConvertI32U => Some(Instr::FConvertI(
756                    FloatWidth::F64,
757                    IntWidth::I32,
758                    Signedness::Unsigned,
759                )),
760                Operator::F64ConvertI64S => Some(Instr::FConvertI(
761                    FloatWidth::F64,
762                    IntWidth::I64,
763                    Signedness::Signed,
764                )),
765                Operator::F64ConvertI64U => Some(Instr::FConvertI(
766                    FloatWidth::F64,
767                    IntWidth::I64,
768                    Signedness::Unsigned,
769                )),
770                Operator::F64PromoteF32 => Some(Instr::F64PromoteF32),
771                Operator::I32ReinterpretF32 => Some(Instr::IReinterpretF(IntWidth::I32)),
772                Operator::I64ReinterpretF64 => Some(Instr::IReinterpretF(IntWidth::I64)),
773                Operator::F32ReinterpretI32 => Some(Instr::FReinterpretI(FloatWidth::F32)),
774                Operator::F64ReinterpretI64 => Some(Instr::FReinterpretI(FloatWidth::F64)),
775                Operator::I32Extend8S => Some(Instr::IExtend8S(IntWidth::I32)),
776                Operator::I32Extend16S => Some(Instr::IExtend16S(IntWidth::I32)),
777                Operator::I64Extend8S => Some(Instr::IExtend8S(IntWidth::I64)),
778                Operator::I64Extend16S => Some(Instr::IExtend16S(IntWidth::I64)),
779                Operator::I64Extend32S => Some(Instr::I64Extend32S),
780                Operator::RefI31 => {
781                    return Err("GC proposal is not supported".to_string());
782                }
783                Operator::I31GetS => {
784                    return Err("GC proposal is not supported".to_string());
785                }
786                Operator::I31GetU => {
787                    return Err("GC proposal is not supported".to_string());
788                }
789                Operator::I32TruncSatF32S => Some(Instr::ITruncSatF(
790                    IntWidth::I32,
791                    FloatWidth::F32,
792                    Signedness::Signed,
793                )),
794                Operator::I32TruncSatF32U => Some(Instr::ITruncSatF(
795                    IntWidth::I32,
796                    FloatWidth::F32,
797                    Signedness::Unsigned,
798                )),
799                Operator::I32TruncSatF64S => Some(Instr::ITruncSatF(
800                    IntWidth::I32,
801                    FloatWidth::F64,
802                    Signedness::Signed,
803                )),
804                Operator::I32TruncSatF64U => Some(Instr::ITruncSatF(
805                    IntWidth::I32,
806                    FloatWidth::F64,
807                    Signedness::Unsigned,
808                )),
809                Operator::I64TruncSatF32S => Some(Instr::ITruncSatF(
810                    IntWidth::I64,
811                    FloatWidth::F32,
812                    Signedness::Signed,
813                )),
814                Operator::I64TruncSatF32U => Some(Instr::ITruncSatF(
815                    IntWidth::I64,
816                    FloatWidth::F32,
817                    Signedness::Unsigned,
818                )),
819                Operator::I64TruncSatF64S => Some(Instr::ITruncSatF(
820                    IntWidth::I64,
821                    FloatWidth::F64,
822                    Signedness::Signed,
823                )),
824                Operator::I64TruncSatF64U => Some(Instr::ITruncSatF(
825                    IntWidth::I64,
826                    FloatWidth::F64,
827                    Signedness::Unsigned,
828                )),
829                Operator::MemoryInit { data_index, .. } => Some(Instr::MemoryInit(data_index)),
830                Operator::DataDrop { data_index } => Some(Instr::DataDrop(data_index)),
831                Operator::MemoryCopy { .. } => Some(Instr::MemoryCopy),
832                Operator::MemoryFill { .. } => Some(Instr::MemoryFill),
833                Operator::TableInit { elem_index, table } => {
834                    Some(Instr::TableInit(table, elem_index))
835                }
836                Operator::ElemDrop { elem_index } => Some(Instr::ElemDrop(elem_index)),
837                Operator::TableCopy {
838                    dst_table,
839                    src_table,
840                } => Some(Instr::TableCopy {
841                    source: src_table,
842                    destination: dst_table,
843                }),
844                Operator::TableFill { table } => Some(Instr::TableFill(table)),
845                Operator::TableGet { table } => Some(Instr::TableGet(table)),
846                Operator::TableSet { table } => Some(Instr::TableSet(table)),
847                Operator::TableGrow { table } => Some(Instr::TableGrow(table)),
848                Operator::TableSize { table } => Some(Instr::TableSize(table)),
849                Operator::MemoryDiscard { .. } => {
850                    return Err(
851                        "Fine grained control of memory proposal is not supported".to_string()
852                    );
853                }
854                Operator::MemoryAtomicNotify { .. } => {
855                    return Err("Threads proposal is not supported".to_string());
856                }
857                Operator::MemoryAtomicWait32 { .. } => {
858                    return Err("Threads proposal is not supported".to_string());
859                }
860                Operator::MemoryAtomicWait64 { .. } => {
861                    return Err("Threads proposal is not supported".to_string());
862                }
863                Operator::AtomicFence => {
864                    return Err("Threads proposal is not supported".to_string());
865                }
866                Operator::I32AtomicLoad { .. } => {
867                    return Err("Threads proposal is not supported".to_string());
868                }
869                Operator::I64AtomicLoad { .. } => {
870                    return Err("Threads proposal is not supported".to_string());
871                }
872                Operator::I32AtomicLoad8U { .. } => {
873                    return Err("Threads proposal is not supported".to_string());
874                }
875                Operator::I32AtomicLoad16U { .. } => {
876                    return Err("Threads proposal is not supported".to_string());
877                }
878                Operator::I64AtomicLoad8U { .. } => {
879                    return Err("Threads proposal is not supported".to_string());
880                }
881                Operator::I64AtomicLoad16U { .. } => {
882                    return Err("Threads proposal is not supported".to_string());
883                }
884                Operator::I64AtomicLoad32U { .. } => {
885                    return Err("Threads proposal is not supported".to_string());
886                }
887                Operator::I32AtomicStore { .. } => {
888                    return Err("Threads proposal is not supported".to_string());
889                }
890                Operator::I64AtomicStore { .. } => {
891                    return Err("Threads proposal is not supported".to_string());
892                }
893                Operator::I32AtomicStore8 { .. } => {
894                    return Err("Threads proposal is not supported".to_string());
895                }
896                Operator::I32AtomicStore16 { .. } => {
897                    return Err("Threads proposal is not supported".to_string());
898                }
899                Operator::I64AtomicStore8 { .. } => {
900                    return Err("Threads proposal is not supported".to_string());
901                }
902                Operator::I64AtomicStore16 { .. } => {
903                    return Err("Threads proposal is not supported".to_string());
904                }
905                Operator::I64AtomicStore32 { .. } => {
906                    return Err("Threads proposal is not supported".to_string());
907                }
908                Operator::I32AtomicRmwAdd { .. } => {
909                    return Err("Threads proposal is not supported".to_string());
910                }
911                Operator::I64AtomicRmwAdd { .. } => {
912                    return Err("Threads proposal is not supported".to_string());
913                }
914                Operator::I32AtomicRmw8AddU { .. } => {
915                    return Err("Threads proposal is not supported".to_string());
916                }
917                Operator::I32AtomicRmw16AddU { .. } => {
918                    return Err("Threads proposal is not supported".to_string());
919                }
920                Operator::I64AtomicRmw8AddU { .. } => {
921                    return Err("Threads proposal is not supported".to_string());
922                }
923                Operator::I64AtomicRmw16AddU { .. } => {
924                    return Err("Threads proposal is not supported".to_string());
925                }
926                Operator::I64AtomicRmw32AddU { .. } => {
927                    return Err("Threads proposal is not supported".to_string());
928                }
929                Operator::I32AtomicRmwSub { .. } => {
930                    return Err("Threads proposal is not supported".to_string());
931                }
932                Operator::I64AtomicRmwSub { .. } => {
933                    return Err("Threads proposal is not supported".to_string());
934                }
935                Operator::I32AtomicRmw8SubU { .. } => {
936                    return Err("Threads proposal is not supported".to_string());
937                }
938                Operator::I32AtomicRmw16SubU { .. } => {
939                    return Err("Threads proposal is not supported".to_string());
940                }
941                Operator::I64AtomicRmw8SubU { .. } => {
942                    return Err("Threads proposal is not supported".to_string());
943                }
944                Operator::I64AtomicRmw16SubU { .. } => {
945                    return Err("Threads proposal is not supported".to_string());
946                }
947                Operator::I64AtomicRmw32SubU { .. } => {
948                    return Err("Threads proposal is not supported".to_string());
949                }
950                Operator::I32AtomicRmwAnd { .. } => {
951                    return Err("Threads proposal is not supported".to_string());
952                }
953                Operator::I64AtomicRmwAnd { .. } => {
954                    return Err("Threads proposal is not supported".to_string());
955                }
956                Operator::I32AtomicRmw8AndU { .. } => {
957                    return Err("Threads proposal is not supported".to_string());
958                }
959                Operator::I32AtomicRmw16AndU { .. } => {
960                    return Err("Threads proposal is not supported".to_string());
961                }
962                Operator::I64AtomicRmw8AndU { .. } => {
963                    return Err("Threads proposal is not supported".to_string());
964                }
965                Operator::I64AtomicRmw16AndU { .. } => {
966                    return Err("Threads proposal is not supported".to_string());
967                }
968                Operator::I64AtomicRmw32AndU { .. } => {
969                    return Err("Threads proposal is not supported".to_string());
970                }
971                Operator::I32AtomicRmwOr { .. } => {
972                    return Err("Threads proposal is not supported".to_string());
973                }
974                Operator::I64AtomicRmwOr { .. } => {
975                    return Err("Threads proposal is not supported".to_string());
976                }
977                Operator::I32AtomicRmw8OrU { .. } => {
978                    return Err("Threads proposal is not supported".to_string());
979                }
980                Operator::I32AtomicRmw16OrU { .. } => {
981                    return Err("Threads proposal is not supported".to_string());
982                }
983                Operator::I64AtomicRmw8OrU { .. } => {
984                    return Err("Threads proposal is not supported".to_string());
985                }
986                Operator::I64AtomicRmw16OrU { .. } => {
987                    return Err("Threads proposal is not supported".to_string());
988                }
989                Operator::I64AtomicRmw32OrU { .. } => {
990                    return Err("Threads proposal is not supported".to_string());
991                }
992                Operator::I32AtomicRmwXor { .. } => {
993                    return Err("Threads proposal is not supported".to_string());
994                }
995                Operator::I64AtomicRmwXor { .. } => {
996                    return Err("Threads proposal is not supported".to_string());
997                }
998                Operator::I32AtomicRmw8XorU { .. } => {
999                    return Err("Threads proposal is not supported".to_string());
1000                }
1001                Operator::I32AtomicRmw16XorU { .. } => {
1002                    return Err("Threads proposal is not supported".to_string());
1003                }
1004                Operator::I64AtomicRmw8XorU { .. } => {
1005                    return Err("Threads proposal is not supported".to_string());
1006                }
1007                Operator::I64AtomicRmw16XorU { .. } => {
1008                    return Err("Threads proposal is not supported".to_string());
1009                }
1010                Operator::I64AtomicRmw32XorU { .. } => {
1011                    return Err("Threads proposal is not supported".to_string());
1012                }
1013                Operator::I32AtomicRmwXchg { .. } => {
1014                    return Err("Threads proposal is not supported".to_string());
1015                }
1016                Operator::I64AtomicRmwXchg { .. } => {
1017                    return Err("Threads proposal is not supported".to_string());
1018                }
1019                Operator::I32AtomicRmw8XchgU { .. } => {
1020                    return Err("Threads proposal is not supported".to_string());
1021                }
1022                Operator::I32AtomicRmw16XchgU { .. } => {
1023                    return Err("Threads proposal is not supported".to_string());
1024                }
1025                Operator::I64AtomicRmw8XchgU { .. } => {
1026                    return Err("Threads proposal is not supported".to_string());
1027                }
1028                Operator::I64AtomicRmw16XchgU { .. } => {
1029                    return Err("Threads proposal is not supported".to_string());
1030                }
1031                Operator::I64AtomicRmw32XchgU { .. } => {
1032                    return Err("Threads proposal is not supported".to_string());
1033                }
1034                Operator::I32AtomicRmwCmpxchg { .. } => {
1035                    return Err("Threads proposal is not supported".to_string());
1036                }
1037                Operator::I64AtomicRmwCmpxchg { .. } => {
1038                    return Err("Threads proposal is not supported".to_string());
1039                }
1040                Operator::I32AtomicRmw8CmpxchgU { .. } => {
1041                    return Err("Threads proposal is not supported".to_string());
1042                }
1043                Operator::I32AtomicRmw16CmpxchgU { .. } => {
1044                    return Err("Threads proposal is not supported".to_string());
1045                }
1046                Operator::I64AtomicRmw8CmpxchgU { .. } => {
1047                    return Err("Threads proposal is not supported".to_string());
1048                }
1049                Operator::I64AtomicRmw16CmpxchgU { .. } => {
1050                    return Err("Threads proposal is not supported".to_string());
1051                }
1052                Operator::I64AtomicRmw32CmpxchgU { .. } => {
1053                    return Err("Threads proposal is not supported".to_string());
1054                }
1055                Operator::V128Load { memarg } => Some(Instr::Load(
1056                    NumOrVecType::Vec(VecType::V128),
1057                    memarg.try_into()?,
1058                )),
1059                Operator::V128Load8x8S { memarg } => {
1060                    Some(Instr::V128Load8x8(Signedness::Signed, memarg.try_into()?))
1061                }
1062                Operator::V128Load8x8U { memarg } => {
1063                    Some(Instr::V128Load8x8(Signedness::Unsigned, memarg.try_into()?))
1064                }
1065                Operator::V128Load16x4S { memarg } => {
1066                    Some(Instr::V128Load16x4(Signedness::Signed, memarg.try_into()?))
1067                }
1068                Operator::V128Load16x4U { memarg } => Some(Instr::V128Load16x4(
1069                    Signedness::Unsigned,
1070                    memarg.try_into()?,
1071                )),
1072                Operator::V128Load32x2S { memarg } => {
1073                    Some(Instr::V128Load32x2(Signedness::Signed, memarg.try_into()?))
1074                }
1075                Operator::V128Load32x2U { memarg } => Some(Instr::V128Load32x2(
1076                    Signedness::Unsigned,
1077                    memarg.try_into()?,
1078                )),
1079                Operator::V128Load8Splat { memarg } => Some(Instr::V128LoadSplat(
1080                    VectorLoadShape::WW8,
1081                    memarg.try_into()?,
1082                )),
1083                Operator::V128Load16Splat { memarg } => Some(Instr::V128LoadSplat(
1084                    VectorLoadShape::WW16,
1085                    memarg.try_into()?,
1086                )),
1087                Operator::V128Load32Splat { memarg } => Some(Instr::V128LoadSplat(
1088                    VectorLoadShape::WW32,
1089                    memarg.try_into()?,
1090                )),
1091                Operator::V128Load64Splat { memarg } => Some(Instr::V128LoadSplat(
1092                    VectorLoadShape::WW64,
1093                    memarg.try_into()?,
1094                )),
1095                Operator::V128Load32Zero { memarg } => {
1096                    Some(Instr::V128Load32Zero(memarg.try_into()?))
1097                }
1098                Operator::V128Load64Zero { memarg } => {
1099                    Some(Instr::V128Load64Zero(memarg.try_into()?))
1100                }
1101                Operator::V128Store { memarg } => Some(Instr::Store(
1102                    NumOrVecType::Vec(VecType::V128),
1103                    memarg.try_into()?,
1104                )),
1105                Operator::V128Load8Lane { memarg, lane } => Some(Instr::V128LoadLane(
1106                    VectorLoadShape::WW8,
1107                    memarg.try_into()?,
1108                    lane,
1109                )),
1110                Operator::V128Load16Lane { memarg, lane } => Some(Instr::V128LoadLane(
1111                    VectorLoadShape::WW16,
1112                    memarg.try_into()?,
1113                    lane,
1114                )),
1115                Operator::V128Load32Lane { memarg, lane } => Some(Instr::V128LoadLane(
1116                    VectorLoadShape::WW32,
1117                    memarg.try_into()?,
1118                    lane,
1119                )),
1120                Operator::V128Load64Lane { memarg, lane } => Some(Instr::V128LoadLane(
1121                    VectorLoadShape::WW64,
1122                    memarg.try_into()?,
1123                    lane,
1124                )),
1125                Operator::V128Store8Lane { memarg, lane } => Some(Instr::V128StoreLane(
1126                    VectorLoadShape::WW8,
1127                    memarg.try_into()?,
1128                    lane,
1129                )),
1130                Operator::V128Store16Lane { memarg, lane } => Some(Instr::V128StoreLane(
1131                    VectorLoadShape::WW16,
1132                    memarg.try_into()?,
1133                    lane,
1134                )),
1135                Operator::V128Store32Lane { memarg, lane } => Some(Instr::V128StoreLane(
1136                    VectorLoadShape::WW32,
1137                    memarg.try_into()?,
1138                    lane,
1139                )),
1140                Operator::V128Store64Lane { memarg, lane } => Some(Instr::V128StoreLane(
1141                    VectorLoadShape::WW64,
1142                    memarg.try_into()?,
1143                    lane,
1144                )),
1145                Operator::V128Const { value } => Some(Instr::V128Const(value.i128())),
1146                Operator::I8x16Shuffle { lanes } => Some(Instr::VI8x16Shuffle(lanes)),
1147                Operator::I8x16ExtractLaneS { lane } => {
1148                    Some(Instr::VI8x16ExtractLane(Signedness::Signed, lane))
1149                }
1150                Operator::I8x16ExtractLaneU { lane } => {
1151                    Some(Instr::VI8x16ExtractLane(Signedness::Unsigned, lane))
1152                }
1153                Operator::I8x16ReplaceLane { lane } => {
1154                    Some(Instr::VReplaceLane(Shape::Int(IShape::I8x16), lane))
1155                }
1156                Operator::I16x8ExtractLaneS { lane } => {
1157                    Some(Instr::VI16x8ExtractLane(Signedness::Signed, lane))
1158                }
1159                Operator::I16x8ExtractLaneU { lane } => {
1160                    Some(Instr::VI16x8ExtractLane(Signedness::Unsigned, lane))
1161                }
1162                Operator::I16x8ReplaceLane { lane } => {
1163                    Some(Instr::VReplaceLane(Shape::Int(IShape::I16x8), lane))
1164                }
1165                Operator::I32x4ExtractLane { lane } => Some(Instr::VI32x4ExtractLane(lane)),
1166                Operator::I32x4ReplaceLane { lane } => {
1167                    Some(Instr::VReplaceLane(Shape::Int(IShape::I32x4), lane))
1168                }
1169                Operator::I64x2ExtractLane { lane } => Some(Instr::VI64x2ExtractLane(lane)),
1170                Operator::I64x2ReplaceLane { lane } => {
1171                    Some(Instr::VReplaceLane(Shape::Int(IShape::I64x2), lane))
1172                }
1173                Operator::F32x4ExtractLane { lane } => {
1174                    Some(Instr::VFExtractLane(FShape::F32x4, lane))
1175                }
1176                Operator::F32x4ReplaceLane { lane } => {
1177                    Some(Instr::VReplaceLane(Shape::Float(FShape::F32x4), lane))
1178                }
1179                Operator::F64x2ExtractLane { lane } => {
1180                    Some(Instr::VFExtractLane(FShape::F64x2, lane))
1181                }
1182                Operator::F64x2ReplaceLane { lane } => {
1183                    Some(Instr::VReplaceLane(Shape::Float(FShape::F64x2), lane))
1184                }
1185                Operator::I8x16Swizzle => Some(Instr::VI18x16Swizzle),
1186                Operator::I8x16Splat => Some(Instr::VSplat(Shape::Int(IShape::I8x16))),
1187                Operator::I16x8Splat => Some(Instr::VSplat(Shape::Int(IShape::I16x8))),
1188                Operator::I32x4Splat => Some(Instr::VSplat(Shape::Int(IShape::I32x4))),
1189                Operator::I64x2Splat => Some(Instr::VSplat(Shape::Int(IShape::I64x2))),
1190                Operator::F32x4Splat => Some(Instr::VSplat(Shape::Float(FShape::F32x4))),
1191                Operator::F64x2Splat => Some(Instr::VSplat(Shape::Float(FShape::F64x2))),
1192                Operator::I8x16Eq => Some(Instr::VIEq(IShape::I8x16)),
1193                Operator::I8x16Ne => Some(Instr::VIEq(IShape::I8x16)),
1194                Operator::I8x16LtS => Some(Instr::VILt(IShape::I8x16, Signedness::Signed)),
1195                Operator::I8x16LtU => Some(Instr::VILt(IShape::I8x16, Signedness::Unsigned)),
1196                Operator::I8x16GtS => Some(Instr::VIGt(IShape::I8x16, Signedness::Signed)),
1197                Operator::I8x16GtU => Some(Instr::VIGt(IShape::I8x16, Signedness::Unsigned)),
1198                Operator::I8x16LeS => Some(Instr::VILe(IShape::I8x16, Signedness::Signed)),
1199                Operator::I8x16LeU => Some(Instr::VILe(IShape::I8x16, Signedness::Unsigned)),
1200                Operator::I8x16GeS => Some(Instr::VIGe(IShape::I8x16, Signedness::Signed)),
1201                Operator::I8x16GeU => Some(Instr::VIGe(IShape::I8x16, Signedness::Unsigned)),
1202                Operator::I16x8Eq => Some(Instr::VIEq(IShape::I16x8)),
1203                Operator::I16x8Ne => Some(Instr::VIEq(IShape::I16x8)),
1204                Operator::I16x8LtS => Some(Instr::VILt(IShape::I16x8, Signedness::Signed)),
1205                Operator::I16x8LtU => Some(Instr::VILt(IShape::I16x8, Signedness::Unsigned)),
1206                Operator::I16x8GtS => Some(Instr::VIGt(IShape::I16x8, Signedness::Signed)),
1207                Operator::I16x8GtU => Some(Instr::VIGt(IShape::I16x8, Signedness::Unsigned)),
1208                Operator::I16x8LeS => Some(Instr::VILe(IShape::I16x8, Signedness::Signed)),
1209                Operator::I16x8LeU => Some(Instr::VILe(IShape::I16x8, Signedness::Unsigned)),
1210                Operator::I16x8GeS => Some(Instr::VIGe(IShape::I16x8, Signedness::Signed)),
1211                Operator::I16x8GeU => Some(Instr::VIGe(IShape::I16x8, Signedness::Unsigned)),
1212                Operator::I32x4Eq => Some(Instr::VIEq(IShape::I32x4)),
1213                Operator::I32x4Ne => Some(Instr::VIEq(IShape::I32x4)),
1214                Operator::I32x4LtS => Some(Instr::VILt(IShape::I32x4, Signedness::Signed)),
1215                Operator::I32x4LtU => Some(Instr::VILt(IShape::I32x4, Signedness::Unsigned)),
1216                Operator::I32x4GtS => Some(Instr::VIGt(IShape::I32x4, Signedness::Signed)),
1217                Operator::I32x4GtU => Some(Instr::VIGt(IShape::I32x4, Signedness::Unsigned)),
1218                Operator::I32x4LeS => Some(Instr::VILe(IShape::I32x4, Signedness::Signed)),
1219                Operator::I32x4LeU => Some(Instr::VILe(IShape::I32x4, Signedness::Unsigned)),
1220                Operator::I32x4GeS => Some(Instr::VIGe(IShape::I32x4, Signedness::Signed)),
1221                Operator::I32x4GeU => Some(Instr::VIGe(IShape::I32x4, Signedness::Unsigned)),
1222                Operator::I64x2Eq => Some(Instr::VIEq(IShape::I64x2)),
1223                Operator::I64x2Ne => Some(Instr::VIEq(IShape::I64x2)),
1224                Operator::I64x2LtS => Some(Instr::VILt(IShape::I64x2, Signedness::Signed)),
1225                Operator::I64x2GtS => Some(Instr::VIGt(IShape::I64x2, Signedness::Signed)),
1226                Operator::I64x2LeS => Some(Instr::VILe(IShape::I64x2, Signedness::Signed)),
1227                Operator::I64x2GeS => Some(Instr::VIGe(IShape::I64x2, Signedness::Signed)),
1228                Operator::F32x4Eq => Some(Instr::VFEq(FShape::F32x4)),
1229                Operator::F32x4Ne => Some(Instr::VFEq(FShape::F32x4)),
1230                Operator::F32x4Lt => Some(Instr::VFLt(FShape::F32x4)),
1231                Operator::F32x4Gt => Some(Instr::VFGt(FShape::F32x4)),
1232                Operator::F32x4Le => Some(Instr::VFLe(FShape::F32x4)),
1233                Operator::F32x4Ge => Some(Instr::VFGe(FShape::F32x4)),
1234                Operator::F64x2Eq => Some(Instr::VFEq(FShape::F64x2)),
1235                Operator::F64x2Ne => Some(Instr::VFEq(FShape::F64x2)),
1236                Operator::F64x2Lt => Some(Instr::VFLt(FShape::F64x2)),
1237                Operator::F64x2Gt => Some(Instr::VFGt(FShape::F64x2)),
1238                Operator::F64x2Le => Some(Instr::VFLe(FShape::F64x2)),
1239                Operator::F64x2Ge => Some(Instr::VFGe(FShape::F64x2)),
1240                Operator::V128Not => Some(Instr::V128Not),
1241                Operator::V128And => Some(Instr::V128And),
1242                Operator::V128AndNot => Some(Instr::V128AndNot),
1243                Operator::V128Or => Some(Instr::V128Or),
1244                Operator::V128Xor => Some(Instr::V128XOr),
1245                Operator::V128Bitselect => Some(Instr::V128BitSelect),
1246                Operator::V128AnyTrue => Some(Instr::V128AnyTrue),
1247                Operator::I8x16Abs => Some(Instr::VIAbs(IShape::I8x16)),
1248                Operator::I8x16Neg => Some(Instr::VINeg(IShape::I8x16)),
1249                Operator::I8x16Popcnt => Some(Instr::VI8x16PopCnt),
1250                Operator::I8x16AllTrue => Some(Instr::VIAllTrue(IShape::I8x16)),
1251                Operator::I8x16Bitmask => Some(Instr::VIBitMask(IShape::I8x16)),
1252                Operator::I8x16NarrowI16x8S => Some(Instr::VI8x16NarrowI16x8(Signedness::Signed)),
1253                Operator::I8x16NarrowI16x8U => Some(Instr::VI8x16NarrowI16x8(Signedness::Unsigned)),
1254                Operator::I8x16Shl => Some(Instr::VIShl(IShape::I8x16)),
1255                Operator::I8x16ShrS => Some(Instr::VIShr(IShape::I8x16, Signedness::Signed)),
1256                Operator::I8x16ShrU => Some(Instr::VIShr(IShape::I8x16, Signedness::Unsigned)),
1257                Operator::I8x16Add => Some(Instr::VIAdd(IShape::I8x16)),
1258                Operator::I8x16AddSatS => Some(Instr::VIAddSat(IShape::I8x16, Signedness::Signed)),
1259                Operator::I8x16AddSatU => {
1260                    Some(Instr::VIAddSat(IShape::I8x16, Signedness::Unsigned))
1261                }
1262                Operator::I8x16Sub => Some(Instr::VISub(IShape::I8x16)),
1263                Operator::I8x16SubSatS => Some(Instr::VISubSat(IShape::I8x16, Signedness::Signed)),
1264                Operator::I8x16SubSatU => {
1265                    Some(Instr::VISubSat(IShape::I8x16, Signedness::Unsigned))
1266                }
1267                Operator::I8x16MinS => Some(Instr::VIMin(IShape::I8x16, Signedness::Signed)),
1268                Operator::I8x16MinU => Some(Instr::VIMin(IShape::I8x16, Signedness::Unsigned)),
1269                Operator::I8x16MaxS => Some(Instr::VIMax(IShape::I8x16, Signedness::Signed)),
1270                Operator::I8x16MaxU => Some(Instr::VIMax(IShape::I8x16, Signedness::Unsigned)),
1271                Operator::I8x16AvgrU => Some(Instr::VIAvgr(IShape::I8x16)),
1272                Operator::I16x8ExtAddPairwiseI8x16S => {
1273                    Some(Instr::VIExtAddPairwise(IShape::I16x8, Signedness::Signed))
1274                }
1275                Operator::I16x8ExtAddPairwiseI8x16U => {
1276                    Some(Instr::VIExtAddPairwise(IShape::I16x8, Signedness::Unsigned))
1277                }
1278                Operator::I16x8Abs => Some(Instr::VIAbs(IShape::I16x8)),
1279                Operator::I16x8Neg => Some(Instr::VINeg(IShape::I16x8)),
1280                Operator::I16x8Q15MulrSatS => Some(Instr::VI16x8Q15MulrSat),
1281                Operator::I16x8AllTrue => Some(Instr::VIAllTrue(IShape::I16x8)),
1282                Operator::I16x8Bitmask => Some(Instr::VIBitMask(IShape::I16x8)),
1283                Operator::I16x8NarrowI32x4S => Some(Instr::VI16x8NarrowI32x4(Signedness::Signed)),
1284                Operator::I16x8NarrowI32x4U => Some(Instr::VI16x8NarrowI32x4(Signedness::Unsigned)),
1285                Operator::I16x8ExtendLowI8x16S => {
1286                    Some(Instr::VI16x8ExtendI8x16(Half::Low, Signedness::Signed))
1287                }
1288                Operator::I16x8ExtendHighI8x16S => {
1289                    Some(Instr::VI16x8ExtendI8x16(Half::High, Signedness::Signed))
1290                }
1291                Operator::I16x8ExtendLowI8x16U => {
1292                    Some(Instr::VI16x8ExtendI8x16(Half::Low, Signedness::Unsigned))
1293                }
1294                Operator::I16x8ExtendHighI8x16U => {
1295                    Some(Instr::VI16x8ExtendI8x16(Half::High, Signedness::Unsigned))
1296                }
1297                Operator::I16x8Shl => Some(Instr::VIShl(IShape::I16x8)),
1298                Operator::I16x8ShrS => Some(Instr::VIShr(IShape::I16x8, Signedness::Signed)),
1299                Operator::I16x8ShrU => Some(Instr::VIShr(IShape::I16x8, Signedness::Unsigned)),
1300                Operator::I16x8Add => Some(Instr::VIAdd(IShape::I16x8)),
1301                Operator::I16x8AddSatS => Some(Instr::VIAddSat(IShape::I16x8, Signedness::Signed)),
1302                Operator::I16x8AddSatU => {
1303                    Some(Instr::VIAddSat(IShape::I16x8, Signedness::Unsigned))
1304                }
1305                Operator::I16x8Sub => Some(Instr::VISub(IShape::I16x8)),
1306                Operator::I16x8SubSatS => Some(Instr::VISubSat(IShape::I16x8, Signedness::Signed)),
1307                Operator::I16x8SubSatU => {
1308                    Some(Instr::VISubSat(IShape::I16x8, Signedness::Unsigned))
1309                }
1310                Operator::I16x8Mul => Some(Instr::VIMul(IShape::I16x8)),
1311                Operator::I16x8MinS => Some(Instr::VIMin(IShape::I16x8, Signedness::Signed)),
1312                Operator::I16x8MinU => Some(Instr::VIMin(IShape::I16x8, Signedness::Unsigned)),
1313                Operator::I16x8MaxS => Some(Instr::VIMax(IShape::I16x8, Signedness::Signed)),
1314                Operator::I16x8MaxU => Some(Instr::VIMax(IShape::I16x8, Signedness::Unsigned)),
1315                Operator::I16x8AvgrU => Some(Instr::VIAvgr(IShape::I16x8)),
1316                Operator::I16x8ExtMulLowI8x16S => Some(Instr::VIExtMul(
1317                    IShape::I16x8,
1318                    Half::Low,
1319                    Signedness::Signed,
1320                )),
1321                Operator::I16x8ExtMulHighI8x16S => Some(Instr::VIExtMul(
1322                    IShape::I16x8,
1323                    Half::High,
1324                    Signedness::Signed,
1325                )),
1326                Operator::I16x8ExtMulLowI8x16U => Some(Instr::VIExtMul(
1327                    IShape::I16x8,
1328                    Half::Low,
1329                    Signedness::Unsigned,
1330                )),
1331                Operator::I16x8ExtMulHighI8x16U => Some(Instr::VIExtMul(
1332                    IShape::I16x8,
1333                    Half::High,
1334                    Signedness::Unsigned,
1335                )),
1336                Operator::I32x4ExtAddPairwiseI16x8S => {
1337                    Some(Instr::VIExtAddPairwise(IShape::I32x4, Signedness::Signed))
1338                }
1339                Operator::I32x4ExtAddPairwiseI16x8U => {
1340                    Some(Instr::VIExtAddPairwise(IShape::I32x4, Signedness::Unsigned))
1341                }
1342                Operator::I32x4Abs => Some(Instr::VIAbs(IShape::I32x4)),
1343                Operator::I32x4Neg => Some(Instr::VINeg(IShape::I32x4)),
1344                Operator::I32x4AllTrue => Some(Instr::VIAllTrue(IShape::I32x4)),
1345                Operator::I32x4Bitmask => Some(Instr::VIBitMask(IShape::I32x4)),
1346                Operator::I32x4ExtendLowI16x8S => {
1347                    Some(Instr::VI32x4ExtendI16x8(Half::Low, Signedness::Signed))
1348                }
1349                Operator::I32x4ExtendHighI16x8S => {
1350                    Some(Instr::VI32x4ExtendI16x8(Half::High, Signedness::Signed))
1351                }
1352                Operator::I32x4ExtendLowI16x8U => {
1353                    Some(Instr::VI32x4ExtendI16x8(Half::Low, Signedness::Unsigned))
1354                }
1355                Operator::I32x4ExtendHighI16x8U => {
1356                    Some(Instr::VI32x4ExtendI16x8(Half::High, Signedness::Unsigned))
1357                }
1358                Operator::I32x4Shl => Some(Instr::VIShl(IShape::I32x4)),
1359                Operator::I32x4ShrS => Some(Instr::VIShr(IShape::I32x4, Signedness::Signed)),
1360                Operator::I32x4ShrU => Some(Instr::VIShr(IShape::I32x4, Signedness::Unsigned)),
1361                Operator::I32x4Add => Some(Instr::VIAdd(IShape::I32x4)),
1362                Operator::I32x4Sub => Some(Instr::VISub(IShape::I32x4)),
1363                Operator::I32x4Mul => Some(Instr::VIMul(IShape::I32x4)),
1364                Operator::I32x4MinS => Some(Instr::VIMin(IShape::I32x4, Signedness::Signed)),
1365                Operator::I32x4MinU => Some(Instr::VIMin(IShape::I32x4, Signedness::Unsigned)),
1366                Operator::I32x4MaxS => Some(Instr::VIMax(IShape::I32x4, Signedness::Signed)),
1367                Operator::I32x4MaxU => Some(Instr::VIMax(IShape::I32x4, Signedness::Unsigned)),
1368                Operator::I32x4DotI16x8S => Some(Instr::VI32x4DotI16x8),
1369                Operator::I32x4ExtMulLowI16x8S => Some(Instr::VIExtMul(
1370                    IShape::I32x4,
1371                    Half::Low,
1372                    Signedness::Signed,
1373                )),
1374                Operator::I32x4ExtMulHighI16x8S => Some(Instr::VIExtMul(
1375                    IShape::I32x4,
1376                    Half::High,
1377                    Signedness::Signed,
1378                )),
1379                Operator::I32x4ExtMulLowI16x8U => Some(Instr::VIExtMul(
1380                    IShape::I32x4,
1381                    Half::Low,
1382                    Signedness::Unsigned,
1383                )),
1384                Operator::I32x4ExtMulHighI16x8U => Some(Instr::VIExtMul(
1385                    IShape::I32x4,
1386                    Half::High,
1387                    Signedness::Unsigned,
1388                )),
1389                Operator::I64x2Abs => Some(Instr::VIAbs(IShape::I64x2)),
1390                Operator::I64x2Neg => Some(Instr::VINeg(IShape::I64x2)),
1391                Operator::I64x2AllTrue => Some(Instr::VIAllTrue(IShape::I64x2)),
1392                Operator::I64x2Bitmask => Some(Instr::VIBitMask(IShape::I64x2)),
1393                Operator::I64x2ExtendLowI32x4S => {
1394                    Some(Instr::VI64x2ExtendI32x4(Half::Low, Signedness::Signed))
1395                }
1396                Operator::I64x2ExtendHighI32x4S => {
1397                    Some(Instr::VI64x2ExtendI32x4(Half::High, Signedness::Signed))
1398                }
1399                Operator::I64x2ExtendLowI32x4U => {
1400                    Some(Instr::VI64x2ExtendI32x4(Half::Low, Signedness::Unsigned))
1401                }
1402                Operator::I64x2ExtendHighI32x4U => {
1403                    Some(Instr::VI64x2ExtendI32x4(Half::High, Signedness::Unsigned))
1404                }
1405                Operator::I64x2Shl => Some(Instr::VIShl(IShape::I64x2)),
1406                Operator::I64x2ShrS => Some(Instr::VIShr(IShape::I64x2, Signedness::Signed)),
1407                Operator::I64x2ShrU => Some(Instr::VIShr(IShape::I64x2, Signedness::Unsigned)),
1408                Operator::I64x2Add => Some(Instr::VIAdd(IShape::I64x2)),
1409                Operator::I64x2Sub => Some(Instr::VISub(IShape::I64x2)),
1410                Operator::I64x2Mul => Some(Instr::VIMul(IShape::I64x2)),
1411                Operator::I64x2ExtMulLowI32x4S => Some(Instr::VIExtMul(
1412                    IShape::I64x2,
1413                    Half::Low,
1414                    Signedness::Signed,
1415                )),
1416                Operator::I64x2ExtMulHighI32x4S => Some(Instr::VIExtMul(
1417                    IShape::I64x2,
1418                    Half::High,
1419                    Signedness::Signed,
1420                )),
1421                Operator::I64x2ExtMulLowI32x4U => Some(Instr::VIExtMul(
1422                    IShape::I64x2,
1423                    Half::Low,
1424                    Signedness::Unsigned,
1425                )),
1426                Operator::I64x2ExtMulHighI32x4U => Some(Instr::VIExtMul(
1427                    IShape::I64x2,
1428                    Half::High,
1429                    Signedness::Unsigned,
1430                )),
1431                Operator::F32x4Ceil => Some(Instr::VFCeil(FShape::F32x4)),
1432                Operator::F32x4Floor => Some(Instr::VFFloor(FShape::F32x4)),
1433                Operator::F32x4Trunc => Some(Instr::VFTrunc(FShape::F32x4)),
1434                Operator::F32x4Nearest => Some(Instr::VFNearest(FShape::F32x4)),
1435                Operator::F32x4Abs => Some(Instr::VFAbs(FShape::F32x4)),
1436                Operator::F32x4Neg => Some(Instr::VFNeg(FShape::F32x4)),
1437                Operator::F32x4Sqrt => Some(Instr::VFSqrt(FShape::F32x4)),
1438                Operator::F32x4Add => Some(Instr::VFAdd(FShape::F32x4)),
1439                Operator::F32x4Sub => Some(Instr::VFSub(FShape::F32x4)),
1440                Operator::F32x4Mul => Some(Instr::VFMul(FShape::F32x4)),
1441                Operator::F32x4Div => Some(Instr::VFDiv(FShape::F32x4)),
1442                Operator::F32x4Min => Some(Instr::VFMin(FShape::F32x4)),
1443                Operator::F32x4Max => Some(Instr::VFMax(FShape::F32x4)),
1444                Operator::F32x4PMin => Some(Instr::VFPMin(FShape::F32x4)),
1445                Operator::F32x4PMax => Some(Instr::VFPMax(FShape::F32x4)),
1446                Operator::F64x2Ceil => Some(Instr::VFCeil(FShape::F64x2)),
1447                Operator::F64x2Floor => Some(Instr::VFFloor(FShape::F64x2)),
1448                Operator::F64x2Trunc => Some(Instr::VFTrunc(FShape::F64x2)),
1449                Operator::F64x2Nearest => Some(Instr::VFNearest(FShape::F64x2)),
1450                Operator::F64x2Abs => Some(Instr::VFAbs(FShape::F64x2)),
1451                Operator::F64x2Neg => Some(Instr::VFNeg(FShape::F64x2)),
1452                Operator::F64x2Sqrt => Some(Instr::VFSqrt(FShape::F64x2)),
1453                Operator::F64x2Add => Some(Instr::VFAdd(FShape::F64x2)),
1454                Operator::F64x2Sub => Some(Instr::VFSub(FShape::F64x2)),
1455                Operator::F64x2Mul => Some(Instr::VFMul(FShape::F64x2)),
1456                Operator::F64x2Div => Some(Instr::VFDiv(FShape::F64x2)),
1457                Operator::F64x2Min => Some(Instr::VFMin(FShape::F64x2)),
1458                Operator::F64x2Max => Some(Instr::VFMax(FShape::F64x2)),
1459                Operator::F64x2PMin => Some(Instr::VFPMin(FShape::F64x2)),
1460                Operator::F64x2PMax => Some(Instr::VFPMax(FShape::F64x2)),
1461                Operator::I32x4TruncSatF32x4S => Some(Instr::ITruncSatF(
1462                    IntWidth::I32,
1463                    FloatWidth::F32,
1464                    Signedness::Signed,
1465                )),
1466                Operator::I32x4TruncSatF32x4U => Some(Instr::ITruncSatF(
1467                    IntWidth::I32,
1468                    FloatWidth::F32,
1469                    Signedness::Unsigned,
1470                )),
1471                Operator::F32x4ConvertI32x4S => Some(Instr::FConvertI(
1472                    FloatWidth::F32,
1473                    IntWidth::I32,
1474                    Signedness::Signed,
1475                )),
1476                Operator::F32x4ConvertI32x4U => Some(Instr::FConvertI(
1477                    FloatWidth::F32,
1478                    IntWidth::I32,
1479                    Signedness::Unsigned,
1480                )),
1481                Operator::I32x4TruncSatF64x2SZero => Some(Instr::ITruncSatF(
1482                    IntWidth::I32,
1483                    FloatWidth::F64,
1484                    Signedness::Signed,
1485                )),
1486                Operator::I32x4TruncSatF64x2UZero => Some(Instr::ITruncSatF(
1487                    IntWidth::I32,
1488                    FloatWidth::F64,
1489                    Signedness::Unsigned,
1490                )),
1491                Operator::F64x2ConvertLowI32x4S => Some(Instr::FConvertI(
1492                    FloatWidth::F64,
1493                    IntWidth::I32,
1494                    Signedness::Signed,
1495                )),
1496                Operator::F64x2ConvertLowI32x4U => Some(Instr::FConvertI(
1497                    FloatWidth::F64,
1498                    IntWidth::I32,
1499                    Signedness::Unsigned,
1500                )),
1501                Operator::F32x4DemoteF64x2Zero => Some(Instr::F32DemoteF64),
1502                Operator::F64x2PromoteLowF32x4 => Some(Instr::F64PromoteF32),
1503                Operator::I8x16RelaxedSwizzle => {
1504                    return Err("Relaxed SIMD instructions are not supported".to_string());
1505                }
1506                Operator::I32x4RelaxedTruncF32x4S => {
1507                    return Err("Relaxed SIMD instructions are not supported".to_string());
1508                }
1509                Operator::I32x4RelaxedTruncF32x4U => {
1510                    return Err("Relaxed SIMD instructions are not supported".to_string());
1511                }
1512                Operator::I32x4RelaxedTruncF64x2SZero => {
1513                    return Err("Relaxed SIMD instructions are not supported".to_string());
1514                }
1515                Operator::I32x4RelaxedTruncF64x2UZero => {
1516                    return Err("Relaxed SIMD instructions are not supported".to_string());
1517                }
1518                Operator::F32x4RelaxedMadd => {
1519                    return Err("Relaxed SIMD instructions are not supported".to_string());
1520                }
1521                Operator::F32x4RelaxedNmadd => {
1522                    return Err("Relaxed SIMD instructions are not supported".to_string());
1523                }
1524                Operator::F64x2RelaxedMadd => {
1525                    return Err("Relaxed SIMD instructions are not supported".to_string());
1526                }
1527                Operator::F64x2RelaxedNmadd => {
1528                    return Err("Relaxed SIMD instructions are not supported".to_string());
1529                }
1530                Operator::I8x16RelaxedLaneselect => {
1531                    return Err("Relaxed SIMD instructions are not supported".to_string());
1532                }
1533                Operator::I16x8RelaxedLaneselect => {
1534                    return Err("Relaxed SIMD instructions are not supported".to_string());
1535                }
1536                Operator::I32x4RelaxedLaneselect => {
1537                    return Err("Relaxed SIMD instructions are not supported".to_string());
1538                }
1539                Operator::I64x2RelaxedLaneselect => {
1540                    return Err("Relaxed SIMD instructions are not supported".to_string());
1541                }
1542                Operator::F32x4RelaxedMin => {
1543                    return Err("Relaxed SIMD instructions are not supported".to_string());
1544                }
1545                Operator::F32x4RelaxedMax => {
1546                    return Err("Relaxed SIMD instructions are not supported".to_string());
1547                }
1548                Operator::F64x2RelaxedMin => {
1549                    return Err("Relaxed SIMD instructions are not supported".to_string());
1550                }
1551                Operator::F64x2RelaxedMax => {
1552                    return Err("Relaxed SIMD instructions are not supported".to_string());
1553                }
1554                Operator::I16x8RelaxedQ15mulrS => {
1555                    return Err("Relaxed SIMD instructions are not supported".to_string());
1556                }
1557                Operator::I16x8RelaxedDotI8x16I7x16S => {
1558                    return Err("Relaxed SIMD instructions are not supported".to_string());
1559                }
1560                Operator::I32x4RelaxedDotI8x16I7x16AddS => {
1561                    return Err("Relaxed SIMD instructions are not supported".to_string());
1562                }
1563                Operator::CallRef { .. } => {
1564                    return Err("Function Reference Types Proposal is not supported".to_string());
1565                }
1566                Operator::ReturnCallRef { .. } => {
1567                    return Err("Function Reference Types Proposal is not supported".to_string());
1568                }
1569                Operator::RefAsNonNull => {
1570                    return Err("Function Reference Types Proposal is not supported".to_string());
1571                }
1572                Operator::BrOnNull { .. } => {
1573                    return Err("Function Reference Types Proposal is not supported".to_string());
1574                }
1575                Operator::BrOnNonNull { .. } => {
1576                    return Err("Function Reference Types Proposal is not supported".to_string());
1577                }
1578                Operator::TryTable { .. } => {
1579                    return Err("Exception Handling Proposal is not supported".to_string());
1580                }
1581                Operator::ThrowRef { .. } => {
1582                    return Err("Exception Handling Proposal is not supported".to_string());
1583                }
1584                Operator::RefEq => {
1585                    return Err("GC Proposal is not supported".to_string());
1586                }
1587                Operator::StructNew { .. } => {
1588                    return Err("GC Proposal is not supported".to_string());
1589                }
1590                Operator::StructNewDefault { .. } => {
1591                    return Err("GC Proposal is not supported".to_string());
1592                }
1593                Operator::StructGet { .. } => {
1594                    return Err("GC Proposal is not supported".to_string());
1595                }
1596                Operator::StructGetS { .. } => {
1597                    return Err("GC Proposal is not supported".to_string());
1598                }
1599                Operator::StructGetU { .. } => {
1600                    return Err("GC Proposal is not supported".to_string());
1601                }
1602                Operator::StructSet { .. } => {
1603                    return Err("GC Proposal is not supported".to_string());
1604                }
1605                Operator::ArrayNew { .. } => {
1606                    return Err("GC Proposal is not supported".to_string());
1607                }
1608                Operator::ArrayNewDefault { .. } => {
1609                    return Err("GC Proposal is not supported".to_string());
1610                }
1611                Operator::ArrayNewFixed { .. } => {
1612                    return Err("GC Proposal is not supported".to_string());
1613                }
1614                Operator::ArrayNewData { .. } => {
1615                    return Err("GC Proposal is not supported".to_string());
1616                }
1617                Operator::ArrayNewElem { .. } => {
1618                    return Err("GC Proposal is not supported".to_string());
1619                }
1620                Operator::ArrayGet { .. } => {
1621                    return Err("GC Proposal is not supported".to_string());
1622                }
1623                Operator::ArrayGetS { .. } => {
1624                    return Err("GC Proposal is not supported".to_string());
1625                }
1626                Operator::ArrayGetU { .. } => {
1627                    return Err("GC Proposal is not supported".to_string());
1628                }
1629                Operator::ArraySet { .. } => {
1630                    return Err("GC Proposal is not supported".to_string());
1631                }
1632                Operator::ArrayLen => {
1633                    return Err("GC Proposal is not supported".to_string());
1634                }
1635                Operator::ArrayFill { .. } => {
1636                    return Err("GC Proposal is not supported".to_string());
1637                }
1638                Operator::ArrayCopy { .. } => {
1639                    return Err("GC Proposal is not supported".to_string());
1640                }
1641                Operator::ArrayInitData { .. } => {
1642                    return Err("GC Proposal is not supported".to_string());
1643                }
1644                Operator::ArrayInitElem { .. } => {
1645                    return Err("GC Proposal is not supported".to_string());
1646                }
1647                Operator::RefTestNonNull { .. } => {
1648                    return Err("GC Proposal is not supported".to_string());
1649                }
1650                Operator::RefTestNullable { .. } => {
1651                    return Err("GC Proposal is not supported".to_string());
1652                }
1653                Operator::RefCastNonNull { .. } => {
1654                    return Err("GC Proposal is not supported".to_string());
1655                }
1656                Operator::RefCastNullable { .. } => {
1657                    return Err("GC Proposal is not supported".to_string());
1658                }
1659                Operator::BrOnCast { .. } => {
1660                    return Err("GC Proposal is not supported".to_string());
1661                }
1662                Operator::BrOnCastFail { .. } => {
1663                    return Err("GC Proposal is not supported".to_string());
1664                }
1665                Operator::AnyConvertExtern => {
1666                    return Err("GC Proposal is not supported".to_string());
1667                }
1668                Operator::ExternConvertAny => {
1669                    return Err("GC Proposal is not supported".to_string());
1670                }
1671                Operator::GlobalAtomicGet { .. } => {
1672                    return Err("Shared Everything Threads proposal is not supported".to_string());
1673                }
1674                Operator::GlobalAtomicSet { .. } => {
1675                    return Err("Shared Everything Threads proposal is not supported".to_string());
1676                }
1677                Operator::GlobalAtomicRmwAdd { .. } => {
1678                    return Err("Shared Everything Threads proposal is not supported".to_string());
1679                }
1680                Operator::GlobalAtomicRmwSub { .. } => {
1681                    return Err("Shared Everything Threads proposal is not supported".to_string());
1682                }
1683                Operator::GlobalAtomicRmwAnd { .. } => {
1684                    return Err("Shared Everything Threads proposal is not supported".to_string());
1685                }
1686                Operator::GlobalAtomicRmwOr { .. } => {
1687                    return Err("Shared Everything Threads proposal is not supported".to_string());
1688                }
1689                Operator::GlobalAtomicRmwXor { .. } => {
1690                    return Err("Shared Everything Threads proposal is not supported".to_string());
1691                }
1692                Operator::GlobalAtomicRmwXchg { .. } => {
1693                    return Err("Shared Everything Threads proposal is not supported".to_string());
1694                }
1695                Operator::GlobalAtomicRmwCmpxchg { .. } => {
1696                    return Err("Shared Everything Threads proposal is not supported".to_string());
1697                }
1698                Operator::TableAtomicGet { .. } => {
1699                    return Err("Shared Everything Threads proposal is not supported".to_string());
1700                }
1701                Operator::TableAtomicSet { .. } => {
1702                    return Err("Shared Everything Threads proposal is not supported".to_string());
1703                }
1704                Operator::TableAtomicRmwXchg { .. } => {
1705                    return Err("Shared Everything Threads proposal is not supported".to_string());
1706                }
1707                Operator::TableAtomicRmwCmpxchg { .. } => {
1708                    return Err("Shared Everything Threads proposal is not supported".to_string());
1709                }
1710                Operator::StructAtomicGet { .. } => {
1711                    return Err("Shared Everything Threads proposal is not supported".to_string());
1712                }
1713                Operator::StructAtomicGetS { .. } => {
1714                    return Err("Shared Everything Threads proposal is not supported".to_string());
1715                }
1716                Operator::StructAtomicGetU { .. } => {
1717                    return Err("Shared Everything Threads proposal is not supported".to_string());
1718                }
1719                Operator::StructAtomicSet { .. } => {
1720                    return Err("Shared Everything Threads proposal is not supported".to_string());
1721                }
1722                Operator::StructAtomicRmwAdd { .. } => {
1723                    return Err("Shared Everything Threads proposal is not supported".to_string());
1724                }
1725                Operator::StructAtomicRmwSub { .. } => {
1726                    return Err("Shared Everything Threads proposal is not supported".to_string());
1727                }
1728                Operator::StructAtomicRmwAnd { .. } => {
1729                    return Err("Shared Everything Threads proposal is not supported".to_string());
1730                }
1731                Operator::StructAtomicRmwOr { .. } => {
1732                    return Err("Shared Everything Threads proposal is not supported".to_string());
1733                }
1734                Operator::StructAtomicRmwXor { .. } => {
1735                    return Err("Shared Everything Threads proposal is not supported".to_string());
1736                }
1737                Operator::StructAtomicRmwXchg { .. } => {
1738                    return Err("Shared Everything Threads proposal is not supported".to_string());
1739                }
1740                Operator::StructAtomicRmwCmpxchg { .. } => {
1741                    return Err("Shared Everything Threads proposal is not supported".to_string());
1742                }
1743                Operator::ArrayAtomicGet { .. } => {
1744                    return Err("Shared Everything Threads proposal is not supported".to_string());
1745                }
1746                Operator::ArrayAtomicGetS { .. } => {
1747                    return Err("Shared Everything Threads proposal is not supported".to_string());
1748                }
1749                Operator::ArrayAtomicGetU { .. } => {
1750                    return Err("Shared Everything Threads proposal is not supported".to_string());
1751                }
1752                Operator::ArrayAtomicSet { .. } => {
1753                    return Err("Shared Everything Threads proposal is not supported".to_string());
1754                }
1755                Operator::ArrayAtomicRmwAdd { .. } => {
1756                    return Err("Shared Everything Threads proposal is not supported".to_string());
1757                }
1758                Operator::ArrayAtomicRmwSub { .. } => {
1759                    return Err("Shared Everything Threads proposal is not supported".to_string());
1760                }
1761                Operator::ArrayAtomicRmwAnd { .. } => {
1762                    return Err("Shared Everything Threads proposal is not supported".to_string());
1763                }
1764                Operator::ArrayAtomicRmwOr { .. } => {
1765                    return Err("Shared Everything Threads proposal is not supported".to_string());
1766                }
1767                Operator::ArrayAtomicRmwXor { .. } => {
1768                    return Err("Shared Everything Threads proposal is not supported".to_string());
1769                }
1770                Operator::ArrayAtomicRmwXchg { .. } => {
1771                    return Err("Shared Everything Threads proposal is not supported".to_string());
1772                }
1773                Operator::ArrayAtomicRmwCmpxchg { .. } => {
1774                    return Err("Shared Everything Threads proposal is not supported".to_string());
1775                }
1776                Operator::RefI31Shared => {
1777                    return Err("Shared Everything Threads proposal is not supported".to_string());
1778                }
1779                Operator::ContNew { .. } => {
1780                    return Err("Task Switching proposal is not supported".to_string());
1781                }
1782                Operator::ContBind { .. } => {
1783                    return Err("Task Switching proposal is not supported".to_string());
1784                }
1785                Operator::Suspend { .. } => {
1786                    return Err("Task Switching proposal is not supported".to_string());
1787                }
1788                Operator::Resume { .. } => {
1789                    return Err("Task Switching proposal is not supported".to_string());
1790                }
1791                Operator::ResumeThrow { .. } => {
1792                    return Err("Task Switching proposal is not supported".to_string());
1793                }
1794                Operator::Switch { .. } => {
1795                    return Err("Task Switching proposal is not supported".to_string());
1796                }
1797                Operator::I64Add128 => {
1798                    return Err("Wide Arithmetic proposal is not supported".to_string());
1799                }
1800                Operator::I64Sub128 => {
1801                    return Err("Wide Arithmetic proposal is not supported".to_string());
1802                }
1803                Operator::I64MulWideS => {
1804                    return Err("Wide Arithmetic proposal is not supported".to_string());
1805                }
1806                Operator::I64MulWideU => {
1807                    return Err("Wide Arithmetic proposal is not supported".to_string());
1808                }
1809                _ => return Err(format!("Unsupported operator: {op:?}")),
1810            };
1811
1812            if let Some(instr) = instr {
1813                stack.last_mut().unwrap().push(instr);
1814            }
1815        }
1816
1817        match stack.into_iter().next() {
1818            Some(OperatorTarget::TopLevel(instrs)) => Ok(Expr { instrs }),
1819            _ => Err("Unexpected stack state".to_string()),
1820        }
1821    }
1822}
1823
1824impl<Ast> TryFrom<(Parser, &[u8])> for Sections<CoreIndexSpace, CoreSectionType, CoreSection<Ast>>
1825where
1826    Ast: AstCustomization,
1827    Ast::Expr: TryFromExprSource,
1828    Ast::Data: From<Data<Ast::Expr>>,
1829    Ast::Custom: From<Custom>,
1830{
1831    type Error = String;
1832
1833    fn try_from(value: (Parser, &[u8])) -> Result<Self, Self::Error> {
1834        let (parser, data) = value;
1835        let mut sections = Vec::new();
1836        for payload in parser.parse_all(data) {
1837            let payload = payload.map_err(|e| format!("Error parsing core module: {e:?}"))?;
1838            match payload {
1839                Payload::Version { .. } => {}
1840                Payload::TypeSection(reader) => {
1841                    for tpe in reader.into_iter_err_on_gc_types() {
1842                        let tpe = tpe.map_err(|e| format!("Error parsing core module type section: {e:?}"))?;
1843                        sections.push(CoreSection::Type(tpe.try_into()?));
1844                    }
1845                }
1846                Payload::ImportSection(reader) => {
1847                    for import in reader {
1848                        let import = import.map_err(|e| format!("Error parsing core module import section: {e:?}"))?;
1849                        sections.push(CoreSection::Import(import.try_into()?))
1850                    }
1851                }
1852                Payload::FunctionSection(reader) => {
1853                    for function in reader {
1854                        let type_idx = function.map_err(|e| format!("Error parsing core module function section: {e:?}"))?;
1855                        sections.push(CoreSection::Func(FuncTypeRef { type_idx }));
1856                    }
1857                }
1858                Payload::TableSection(reader) => {
1859                    for table in reader {
1860                        let table = table.map_err(|e| format!("Error parsing core module table section: {e:?}"))?;
1861                        sections.push(CoreSection::Table(table.try_into()?))
1862                    }
1863                }
1864                Payload::MemorySection(reader) => {
1865                    for mem_type in reader {
1866                        let memory = mem_type.map_err(|e| format!("Error parsing core module memory section: {e:?}"))?;
1867                        sections.push(CoreSection::Mem(memory.try_into()?))
1868                    }
1869                }
1870                Payload::TagSection(_) =>
1871                    return Err("Unexpected tag section in core module; exception handling proposal is not supported".to_string()),
1872                Payload::GlobalSection(reader) => {
1873                    for global in reader {
1874                        let global = global.map_err(|e| format!("Error parsing core module global section: {e:?}"))?;
1875                        sections.push(CoreSection::Global(global.try_into()?))
1876                    }
1877                }
1878                Payload::ExportSection(reader) => {
1879                    for export in reader {
1880                        let export = export.map_err(|e| format!("Error parsing core module export section: {e:?}"))?;
1881                        sections.push(CoreSection::Export(export.try_into()?))
1882                    }
1883                }
1884                Payload::StartSection { func, .. } => {
1885                    sections.push(CoreSection::Start(Start { func }))
1886                }
1887                Payload::ElementSection(reader) => {
1888                    for element in reader {
1889                        let element = element.map_err(|e| format!("Error parsing core module element section: {e:?}"))?;
1890                        sections.push(CoreSection::Elem(element.try_into()?))
1891                    }
1892                }
1893                Payload::DataCountSection { count, .. } => {
1894                    sections.push(CoreSection::DataCount(DataCount { count }))
1895                }
1896                Payload::DataSection(reader) => {
1897                    for data in reader {
1898                        let data = data.map_err(|e| format!("Error parsing core module data section: {e:?}"))?;
1899                        let data: Data<Ast::Expr> = data.try_into()?;
1900                        sections.push(CoreSection::Data(data.into()));
1901                    }
1902                }
1903                Payload::CodeSectionStart { .. } => {
1904                    // this is just a marker that the next payload will be CodeSectionEntry
1905                }
1906                Payload::CodeSectionEntry(function_body) => {
1907                    sections.push(CoreSection::Code(function_body.try_into()?))
1908                }
1909                Payload::CustomSection(reader) => {
1910                    sections.push(CoreSection::Custom(Custom {
1911                        name: reader.name().to_string(),
1912                        data: reader.data().to_vec(),
1913                    }.into()))
1914                }
1915                Payload::End(_) => {}
1916                Payload::InstanceSection(_) =>
1917                    return Err("Unexpected component section in core module".to_string()),
1918                Payload::CoreTypeSection(_) =>
1919                    return Err("Unexpected component section in core module".to_string()),
1920                Payload::ModuleSection { .. } =>
1921                    return Err("Unexpected module section in core module".to_string()),
1922                Payload::ComponentSection { .. } =>
1923                    return Err("Unexpected component section in core module".to_string()),
1924                Payload::ComponentInstanceSection(_) =>
1925                    return Err("Unexpected component instance section in core module".to_string()),
1926                Payload::ComponentAliasSection(_) =>
1927                    return Err("Unexpected component alias section in core module".to_string()),
1928                Payload::ComponentTypeSection(_) =>
1929                    return Err("Unexpected component type section in core module".to_string()),
1930                Payload::ComponentCanonicalSection(_) =>
1931                    return Err("Unexpected component canonical section in core module".to_string()),
1932                Payload::ComponentStartSection { .. } =>
1933                    return Err("Unexpected component start section in core module".to_string()),
1934                Payload::ComponentImportSection(_) =>
1935                    return Err("Unexpected component import section in core module".to_string()),
1936                Payload::ComponentExportSection(_) =>
1937                    return Err("Unexpected component export section in core module".to_string()),
1938                Payload::UnknownSection { .. } =>
1939                    return Err("Unexpected unknown section in core module".to_string()),
1940                _ => return Err("Unexpected payload in core module".to_string()),
1941            }
1942        }
1943        Ok(Sections::from_flat(sections))
1944    }
1945}
1946
1947impl<Ast> TryFrom<(Parser, &[u8])> for Module<Ast>
1948where
1949    Ast: AstCustomization,
1950    Ast::Expr: TryFromExprSource,
1951    Ast::Data: From<Data<Ast::Expr>>,
1952    Ast::Custom: From<Custom>,
1953{
1954    type Error = String;
1955
1956    fn try_from(value: (Parser, &[u8])) -> Result<Self, Self::Error> {
1957        let sections =
1958            Sections::<CoreIndexSpace, CoreSectionType, CoreSection<Ast>>::try_from(value)?;
1959        Ok(sections.into())
1960    }
1961}
1962
1963struct OperatorsReaderExprSource<'a> {
1964    reader: OperatorsReader<'a>,
1965}
1966
1967impl<'a> OperatorsReaderExprSource<'a> {
1968    pub fn new(reader: OperatorsReader<'a>) -> Self {
1969        Self { reader }
1970    }
1971}
1972
1973impl ExprSource for OperatorsReaderExprSource<'_> {
1974    fn unparsed(self) -> Result<Vec<u8>, String> {
1975        let binary_reader: BinaryReader = self.reader.get_binary_reader();
1976        let range = binary_reader.range();
1977        let bytes = self.reader.get_binary_reader().read_bytes(range.count());
1978        bytes
1979            .map_err(|e| format!("Error reading bytes from binary reader: {e:?}"))
1980            .map(|bytes| bytes.to_vec())
1981    }
1982}
1983
1984impl IntoIterator for OperatorsReaderExprSource<'_> {
1985    type Item = Result<Instr, String>;
1986    type IntoIter = Box<dyn Iterator<Item = Result<Instr, String>>>;
1987
1988    fn into_iter(self) -> Self::IntoIter {
1989        // TODO: parse incrementally
1990        let expr: Result<Expr, String> = self.reader.try_into();
1991        match expr {
1992            Err(err) => Box::new(vec![Err(err)].into_iter()),
1993            Ok(expr) => Box::new(expr.instrs.into_iter().map(Ok)),
1994        }
1995    }
1996}
1997
1998struct RefFuncExprSource {
1999    func_idx: FuncIdx,
2000}
2001
2002impl RefFuncExprSource {
2003    pub fn new(func_idx: FuncIdx) -> Self {
2004        Self { func_idx }
2005    }
2006}
2007
2008impl ExprSource for RefFuncExprSource {
2009    fn unparsed(self) -> Result<Vec<u8>, String> {
2010        let mut result: Vec<u8> = Vec::new();
2011        result.write_all(&[0xd2u8]).unwrap();
2012        leb128::write::unsigned(&mut result, self.func_idx as u64).unwrap();
2013        result.write_all(&[0x0bu8]).unwrap();
2014        Ok(result)
2015    }
2016}
2017
2018impl IntoIterator for RefFuncExprSource {
2019    type Item = Result<Instr, String>;
2020    type IntoIter = Box<dyn Iterator<Item = Result<Instr, String>>>;
2021
2022    fn into_iter(self) -> Self::IntoIter {
2023        Box::new(vec![Instr::RefFunc(self.func_idx)].into_iter().map(Ok))
2024    }
2025}