golem_wasm_ast/core/
parser.rs

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