radix_wasm_instrument/utils/
translator.rs

1use crate::utils::errors::TranslatorError;
2use alloc::vec::Vec;
3use wasm_encoder::*;
4use wasmparser::{
5	DataKind, ElementKind, ExternalKind, FunctionBody, Global, Import, Operator, Type,
6};
7
8type Result<T> = core::result::Result<T, TranslatorError>;
9
10#[derive(Debug, Hash, Eq, PartialEq, Copy, Clone)]
11pub enum Item {
12	Function,
13	Table,
14	Memory,
15	Tag,
16	Global,
17	Type,
18	Data,
19	Element,
20}
21
22#[allow(dead_code)]
23#[derive(Debug, Hash, Eq, PartialEq, Copy, Clone)]
24pub enum ConstExprKind {
25	Global,
26	ElementOffset,
27	ElementFunction,
28	DataOffset,
29	TableInit,
30}
31
32pub trait Translator {
33	fn as_obj(&mut self) -> &mut dyn Translator;
34
35	fn translate_type_def(&mut self, ty: Type, s: &mut TypeSection) -> Result<()> {
36		type_def(self.as_obj(), ty, s)
37	}
38
39	fn translate_import(&mut self, import: Import, s: &mut ImportSection) -> Result<()> {
40		import_def(self.as_obj(), import, s)
41	}
42
43	fn translate_table_type(
44		&mut self,
45		ty: &wasmparser::TableType,
46	) -> Result<wasm_encoder::TableType> {
47		table_type(self.as_obj(), ty)
48	}
49
50	fn translate_memory_type(
51		&mut self,
52		ty: &wasmparser::MemoryType,
53	) -> Result<wasm_encoder::MemoryType> {
54		memory_type(self.as_obj(), ty)
55	}
56
57	fn translate_global_type(
58		&mut self,
59		ty: &wasmparser::GlobalType,
60	) -> Result<wasm_encoder::GlobalType> {
61		global_type(self.as_obj(), ty)
62	}
63
64	fn translate_tag_type(&mut self, ty: &wasmparser::TagType) -> Result<wasm_encoder::TagType> {
65		tag_type(self.as_obj(), ty)
66	}
67
68	fn translate_ty(&mut self, t: &wasmparser::ValType) -> Result<ValType> {
69		ty(self.as_obj(), t)
70	}
71
72	fn translate_ref_ty(&mut self, t: &wasmparser::RefType) -> Result<RefType> {
73		ref_ty(self.as_obj(), t)
74	}
75
76	fn translate_heap_ty(&mut self, t: &wasmparser::HeapType) -> Result<HeapType> {
77		heap_ty(self.as_obj(), t)
78	}
79
80	fn translate_global(&mut self, g: Global, s: &mut GlobalSection) -> Result<()> {
81		global(self.as_obj(), g, s)
82	}
83
84	fn translate_export_kind(
85		&mut self,
86		g: wasmparser::ExternalKind,
87	) -> Result<wasm_encoder::ExportKind> {
88		export_kind(self.as_obj(), g)
89	}
90
91	fn translate_export(
92		&mut self,
93		e: &wasmparser::Export,
94		sec: &mut wasm_encoder::ExportSection,
95	) -> Result<()> {
96		export(self.as_obj(), e, sec)
97	}
98
99	fn translate_const_expr(
100		&mut self,
101		e: &wasmparser::ConstExpr<'_>,
102		_ty: &wasmparser::ValType,
103		ctx: ConstExprKind,
104	) -> Result<wasm_encoder::ConstExpr> {
105		const_expr(self.as_obj(), e, ctx)
106	}
107
108	fn translate_element(
109		&mut self,
110		e: wasmparser::Element<'_>,
111		s: &mut ElementSection,
112	) -> Result<()> {
113		element(self.as_obj(), e, s)
114	}
115
116	fn translate_data(&mut self, d: wasmparser::Data<'_>, s: &mut DataSection) -> Result<()> {
117		data(self.as_obj(), d, s)
118	}
119
120	fn translate_code(&mut self, body: FunctionBody<'_>, s: &mut CodeSection) -> Result<()> {
121		code(self.as_obj(), body, s)
122	}
123
124	fn translate_op(&mut self, e: &Operator<'_>) -> Result<Instruction<'static>> {
125		op(self.as_obj(), e)
126	}
127
128	fn translate_block_type(&mut self, ty: &wasmparser::BlockType) -> Result<BlockType> {
129		block_type(self.as_obj(), ty)
130	}
131
132	fn translate_memarg(&mut self, arg: &wasmparser::MemArg) -> Result<MemArg> {
133		memarg(self.as_obj(), arg)
134	}
135}
136
137pub struct DefaultTranslator;
138
139impl Translator for DefaultTranslator {
140	fn as_obj(&mut self) -> &mut dyn Translator {
141		self
142	}
143}
144
145pub fn type_def(t: &mut dyn Translator, ty: Type, s: &mut TypeSection) -> Result<()> {
146	match ty {
147		Type::Func(f) => {
148			s.function(
149				f.params().iter().map(|ty| t.translate_ty(ty)).collect::<Result<Vec<_>>>()?,
150				f.results().iter().map(|ty| t.translate_ty(ty)).collect::<Result<Vec<_>>>()?,
151			);
152			Ok(())
153		},
154		Type::Array(_) => unimplemented!("Array and struct types are not supported yet."),
155	}
156}
157
158#[allow(dead_code)]
159pub fn import_def(t: &mut dyn Translator, ty: Import, s: &mut ImportSection) -> Result<()> {
160	let new_ty = match ty.ty {
161		wasmparser::TypeRef::Func(v) => EntityType::Function(v),
162		wasmparser::TypeRef::Tag(v) => EntityType::Tag(t.translate_tag_type(&v)?),
163		wasmparser::TypeRef::Global(v) => EntityType::Global(t.translate_global_type(&v)?),
164		wasmparser::TypeRef::Table(v) => EntityType::Table(t.translate_table_type(&v)?),
165		wasmparser::TypeRef::Memory(v) => EntityType::Memory(t.translate_memory_type(&v)?),
166	};
167	s.import(ty.module, ty.name, new_ty);
168	Ok(())
169}
170
171#[allow(dead_code)]
172pub fn table_type(
173	t: &mut dyn Translator,
174	ty: &wasmparser::TableType,
175) -> Result<wasm_encoder::TableType> {
176	Ok(wasm_encoder::TableType {
177		element_type: t.translate_ref_ty(&ty.element_type)?,
178		minimum: ty.initial,
179		maximum: ty.maximum,
180	})
181}
182
183#[allow(dead_code)]
184pub fn memory_type(
185	_t: &mut dyn Translator,
186	ty: &wasmparser::MemoryType,
187) -> Result<wasm_encoder::MemoryType> {
188	Ok(wasm_encoder::MemoryType {
189		memory64: ty.memory64,
190		minimum: ty.initial,
191		maximum: ty.maximum,
192		shared: ty.shared,
193	})
194}
195
196pub fn global_type(
197	t: &mut dyn Translator,
198	ty: &wasmparser::GlobalType,
199) -> Result<wasm_encoder::GlobalType> {
200	Ok(wasm_encoder::GlobalType {
201		val_type: t.translate_ty(&ty.content_type)?,
202		mutable: ty.mutable,
203	})
204}
205
206#[allow(dead_code)]
207pub fn tag_type(
208	_t: &mut dyn Translator,
209	ty: &wasmparser::TagType,
210) -> Result<wasm_encoder::TagType> {
211	Ok(wasm_encoder::TagType { kind: TagKind::Exception, func_type_idx: ty.func_type_idx })
212}
213
214pub fn ty(t: &mut dyn Translator, ty: &wasmparser::ValType) -> Result<ValType> {
215	match ty {
216		wasmparser::ValType::I32 => Ok(ValType::I32),
217		wasmparser::ValType::I64 => Ok(ValType::I64),
218		wasmparser::ValType::F32 => Ok(ValType::F32),
219		wasmparser::ValType::F64 => Ok(ValType::F64),
220		wasmparser::ValType::V128 => Ok(ValType::V128),
221		wasmparser::ValType::Ref(ty) => Ok(ValType::Ref(t.translate_ref_ty(ty)?)),
222	}
223}
224
225pub fn ref_ty(t: &mut dyn Translator, ty: &wasmparser::RefType) -> Result<RefType> {
226	Ok(RefType { nullable: ty.is_nullable(), heap_type: t.translate_heap_ty(&ty.heap_type())? })
227}
228
229pub fn heap_ty(_t: &mut dyn Translator, ty: &wasmparser::HeapType) -> Result<HeapType> {
230	match ty {
231		wasmparser::HeapType::Func => Ok(HeapType::Func),
232		wasmparser::HeapType::Extern => Ok(HeapType::Extern),
233		wasmparser::HeapType::Any => Ok(HeapType::Any),
234		wasmparser::HeapType::None => Ok(HeapType::None),
235		wasmparser::HeapType::NoExtern => Ok(HeapType::NoExtern),
236		wasmparser::HeapType::NoFunc => Ok(HeapType::NoFunc),
237		wasmparser::HeapType::Eq => Ok(HeapType::Eq),
238		wasmparser::HeapType::Struct => Ok(HeapType::Struct),
239		wasmparser::HeapType::Array => Ok(HeapType::Array),
240		wasmparser::HeapType::I31 => Ok(HeapType::I31),
241		wasmparser::HeapType::Indexed(i) => Ok(HeapType::Indexed(*i)),
242	}
243}
244
245pub fn global(t: &mut dyn Translator, global: Global, s: &mut GlobalSection) -> Result<()> {
246	let ty = t.translate_global_type(&global.ty)?;
247	let insn =
248		t.translate_const_expr(&global.init_expr, &global.ty.content_type, ConstExprKind::Global)?;
249	s.global(ty, &insn);
250	Ok(())
251}
252
253pub fn export_kind(_: &dyn Translator, kind: ExternalKind) -> Result<ExportKind> {
254	match kind {
255		ExternalKind::Table => Ok(ExportKind::Table),
256		ExternalKind::Global => Ok(ExportKind::Global),
257		ExternalKind::Tag => Ok(ExportKind::Tag),
258		ExternalKind::Func => Ok(ExportKind::Func),
259		ExternalKind::Memory => Ok(ExportKind::Memory),
260	}
261}
262
263#[allow(unused)]
264pub fn export(
265	t: &mut dyn Translator,
266	e: &wasmparser::Export<'_>,
267	sec: &mut wasm_encoder::ExportSection,
268) -> Result<()> {
269	sec.export(e.name, t.translate_export_kind(e.kind)?, e.index);
270	Ok(())
271}
272
273pub fn const_expr(
274	t: &mut dyn Translator,
275	e: &wasmparser::ConstExpr<'_>,
276	ctx: ConstExprKind,
277) -> Result<wasm_encoder::ConstExpr> {
278	let mut e = e.get_operators_reader();
279	let mut offset_bytes = Vec::new();
280	let op = e.read()?;
281	if let ConstExprKind::ElementFunction = ctx {
282		match op {
283			Operator::RefFunc { .. } |
284			Operator::RefNull { hty: wasmparser::HeapType::Func, .. } |
285			Operator::GlobalGet { .. } => {},
286			_ => return Err(TranslatorError::NoMutationsApplicable),
287		}
288	}
289	t.translate_op(&op)?.encode(&mut offset_bytes);
290	match e.read()? {
291		Operator::End if e.eof() => {},
292		_ => return Err(TranslatorError::NoMutationsApplicable),
293	}
294	Ok(wasm_encoder::ConstExpr::raw(offset_bytes))
295}
296
297#[allow(dead_code)]
298pub fn element(
299	t: &mut dyn Translator,
300	element: wasmparser::Element<'_>,
301	s: &mut ElementSection,
302) -> Result<()> {
303	let offset;
304	let mode = match &element.kind {
305		ElementKind::Active { table_index, offset_expr } => {
306			offset = t.translate_const_expr(
307				offset_expr,
308				&wasmparser::ValType::I32,
309				ConstExprKind::ElementOffset,
310			)?;
311			ElementMode::Active { table: *table_index, offset: &offset }
312		},
313		ElementKind::Passive => ElementMode::Passive,
314		ElementKind::Declared => ElementMode::Declared,
315	};
316	let element_type = t.translate_ref_ty(&element.ty)?;
317	let functions;
318	let exprs;
319	let elements = match element.items {
320		wasmparser::ElementItems::Functions(reader) => {
321			functions = reader.into_iter().collect::<wasmparser::Result<Vec<_>, _>>()?;
322			Elements::Functions(&functions)
323		},
324		wasmparser::ElementItems::Expressions(reader) => {
325			exprs = reader
326				.into_iter()
327				.map(|f| {
328					t.translate_const_expr(
329						&f?,
330						&wasmparser::ValType::Ref(element.ty),
331						ConstExprKind::ElementFunction,
332					)
333				})
334				.collect::<wasmparser::Result<Vec<_>, _>>()?;
335			Elements::Expressions(&exprs)
336		},
337	};
338	s.segment(ElementSegment { mode, element_type, elements });
339	Ok(())
340}
341
342/// This is a pretty gnarly function that translates from `wasmparser`
343/// operators to `wasm_encoder` operators. It's quite large because there's
344/// quite a few wasm instructions. The theory though is that at least each
345/// individual case is pretty self-contained.
346pub fn op(t: &mut dyn Translator, op: &Operator<'_>) -> Result<Instruction<'static>> {
347	use wasm_encoder::Instruction as I;
348	use wasmparser::Operator as O;
349	Ok(match op {
350		O::Unreachable => I::Unreachable,
351		O::Nop => I::Nop,
352
353		O::Block { blockty } => I::Block(t.translate_block_type(blockty)?),
354		O::Loop { blockty } => I::Loop(t.translate_block_type(blockty)?),
355		O::If { blockty } => I::If(t.translate_block_type(blockty)?),
356		O::Else => I::Else,
357
358		O::Try { blockty } => I::Try(t.translate_block_type(blockty)?),
359		O::Catch { tag_index } => I::Catch(*tag_index),
360		O::Throw { tag_index } => I::Throw(*tag_index),
361		O::Rethrow { relative_depth } => I::Rethrow(*relative_depth),
362		O::End => I::End,
363		O::Br { relative_depth } => I::Br(*relative_depth),
364		O::BrIf { relative_depth } => I::BrIf(*relative_depth),
365		O::BrTable { targets } => I::BrTable(
366			targets.targets().collect::<wasmparser::Result<Vec<_>, _>>()?.into(),
367			targets.default(),
368		),
369
370		O::Return => I::Return,
371		O::Call { function_index } => I::Call(*function_index),
372		O::CallIndirect { type_index, table_index, table_byte: _ } =>
373			I::CallIndirect { ty: *type_index, table: *table_index },
374		O::ReturnCall { function_index } => I::ReturnCall(*function_index),
375		O::ReturnCallIndirect { type_index, table_index } =>
376			I::ReturnCallIndirect { ty: *type_index, table: *table_index },
377		O::Delegate { relative_depth } => I::Delegate(*relative_depth),
378		O::CatchAll => I::CatchAll,
379		O::Drop => I::Drop,
380		O::Select => I::Select,
381		O::TypedSelect { ty } => I::TypedSelect(t.translate_ty(ty)?),
382
383		O::LocalGet { local_index } => I::LocalGet(*local_index),
384		O::LocalSet { local_index } => I::LocalSet(*local_index),
385		O::LocalTee { local_index } => I::LocalTee(*local_index),
386
387		O::GlobalGet { global_index } => I::GlobalGet(*global_index),
388		O::GlobalSet { global_index } => I::GlobalSet(*global_index),
389
390		O::I32Load { memarg } => I::I32Load(t.translate_memarg(memarg)?),
391		O::I64Load { memarg } => I::I64Load(t.translate_memarg(memarg)?),
392		O::F32Load { memarg } => I::F32Load(t.translate_memarg(memarg)?),
393		O::F64Load { memarg } => I::F64Load(t.translate_memarg(memarg)?),
394		O::I32Load8S { memarg } => I::I32Load8S(t.translate_memarg(memarg)?),
395		O::I32Load8U { memarg } => I::I32Load8U(t.translate_memarg(memarg)?),
396		O::I32Load16S { memarg } => I::I32Load16S(t.translate_memarg(memarg)?),
397		O::I32Load16U { memarg } => I::I32Load16U(t.translate_memarg(memarg)?),
398		O::I64Load8S { memarg } => I::I64Load8S(t.translate_memarg(memarg)?),
399		O::I64Load8U { memarg } => I::I64Load8U(t.translate_memarg(memarg)?),
400		O::I64Load16S { memarg } => I::I64Load16S(t.translate_memarg(memarg)?),
401		O::I64Load16U { memarg } => I::I64Load16U(t.translate_memarg(memarg)?),
402		O::I64Load32S { memarg } => I::I64Load32S(t.translate_memarg(memarg)?),
403		O::I64Load32U { memarg } => I::I64Load32U(t.translate_memarg(memarg)?),
404		O::I32Store { memarg } => I::I32Store(t.translate_memarg(memarg)?),
405		O::I64Store { memarg } => I::I64Store(t.translate_memarg(memarg)?),
406		O::F32Store { memarg } => I::F32Store(t.translate_memarg(memarg)?),
407		O::F64Store { memarg } => I::F64Store(t.translate_memarg(memarg)?),
408		O::I32Store8 { memarg } => I::I32Store8(t.translate_memarg(memarg)?),
409		O::I32Store16 { memarg } => I::I32Store16(t.translate_memarg(memarg)?),
410		O::I64Store8 { memarg } => I::I64Store8(t.translate_memarg(memarg)?),
411		O::I64Store16 { memarg } => I::I64Store16(t.translate_memarg(memarg)?),
412		O::I64Store32 { memarg } => I::I64Store32(t.translate_memarg(memarg)?),
413
414		O::MemorySize { mem, .. } => I::MemorySize(*mem),
415		O::MemoryGrow { mem, .. } => I::MemoryGrow(*mem),
416
417		O::I32Const { value } => I::I32Const(*value),
418		O::I64Const { value } => I::I64Const(*value),
419		O::F32Const { value } => I::F32Const(f32::from_bits(value.bits())),
420		O::F64Const { value } => I::F64Const(f64::from_bits(value.bits())),
421
422		O::RefNull { hty } => I::RefNull(t.translate_heap_ty(hty)?),
423		O::RefIsNull => I::RefIsNull,
424		O::RefFunc { function_index } => I::RefFunc(*function_index),
425
426		O::I31New => I::I31New,
427		O::I31GetS => I::I31GetS,
428		O::I31GetU => I::I31GetU,
429
430		O::I32Eqz => I::I32Eqz,
431		O::I32Eq => I::I32Eq,
432		O::I32Ne => I::I32Ne,
433		O::I32LtS => I::I32LtS,
434		O::I32LtU => I::I32LtU,
435		O::I32GtS => I::I32GtS,
436		O::I32GtU => I::I32GtU,
437		O::I32LeS => I::I32LeS,
438		O::I32LeU => I::I32LeU,
439		O::I32GeS => I::I32GeS,
440		O::I32GeU => I::I32GeU,
441		O::I64Eqz => I::I64Eqz,
442		O::I64Eq => I::I64Eq,
443		O::I64Ne => I::I64Ne,
444		O::I64LtS => I::I64LtS,
445		O::I64LtU => I::I64LtU,
446		O::I64GtS => I::I64GtS,
447		O::I64GtU => I::I64GtU,
448		O::I64LeS => I::I64LeS,
449		O::I64LeU => I::I64LeU,
450		O::I64GeS => I::I64GeS,
451		O::I64GeU => I::I64GeU,
452		O::F32Eq => I::F32Eq,
453		O::F32Ne => I::F32Ne,
454		O::F32Lt => I::F32Lt,
455		O::F32Gt => I::F32Gt,
456		O::F32Le => I::F32Le,
457		O::F32Ge => I::F32Ge,
458		O::F64Eq => I::F64Eq,
459		O::F64Ne => I::F64Ne,
460		O::F64Lt => I::F64Lt,
461		O::F64Gt => I::F64Gt,
462		O::F64Le => I::F64Le,
463		O::F64Ge => I::F64Ge,
464		O::I32Clz => I::I32Clz,
465		O::I32Ctz => I::I32Ctz,
466		O::I32Popcnt => I::I32Popcnt,
467		O::I32Add => I::I32Add,
468		O::I32Sub => I::I32Sub,
469		O::I32Mul => I::I32Mul,
470		O::I32DivS => I::I32DivS,
471		O::I32DivU => I::I32DivU,
472		O::I32RemS => I::I32RemS,
473		O::I32RemU => I::I32RemU,
474		O::I32And => I::I32And,
475		O::I32Or => I::I32Or,
476		O::I32Xor => I::I32Xor,
477		O::I32Shl => I::I32Shl,
478		O::I32ShrS => I::I32ShrS,
479		O::I32ShrU => I::I32ShrU,
480		O::I32Rotl => I::I32Rotl,
481		O::I32Rotr => I::I32Rotr,
482		O::I64Clz => I::I64Clz,
483		O::I64Ctz => I::I64Ctz,
484		O::I64Popcnt => I::I64Popcnt,
485		O::I64Add => I::I64Add,
486		O::I64Sub => I::I64Sub,
487		O::I64Mul => I::I64Mul,
488		O::I64DivS => I::I64DivS,
489		O::I64DivU => I::I64DivU,
490		O::I64RemS => I::I64RemS,
491		O::I64RemU => I::I64RemU,
492		O::I64And => I::I64And,
493		O::I64Or => I::I64Or,
494		O::I64Xor => I::I64Xor,
495		O::I64Shl => I::I64Shl,
496		O::I64ShrS => I::I64ShrS,
497		O::I64ShrU => I::I64ShrU,
498		O::I64Rotl => I::I64Rotl,
499		O::I64Rotr => I::I64Rotr,
500		O::F32Abs => I::F32Abs,
501		O::F32Neg => I::F32Neg,
502		O::F32Ceil => I::F32Ceil,
503		O::F32Floor => I::F32Floor,
504		O::F32Trunc => I::F32Trunc,
505		O::F32Nearest => I::F32Nearest,
506		O::F32Sqrt => I::F32Sqrt,
507		O::F32Add => I::F32Add,
508		O::F32Sub => I::F32Sub,
509		O::F32Mul => I::F32Mul,
510		O::F32Div => I::F32Div,
511		O::F32Min => I::F32Min,
512		O::F32Max => I::F32Max,
513		O::F32Copysign => I::F32Copysign,
514		O::F64Abs => I::F64Abs,
515		O::F64Neg => I::F64Neg,
516		O::F64Ceil => I::F64Ceil,
517		O::F64Floor => I::F64Floor,
518		O::F64Trunc => I::F64Trunc,
519		O::F64Nearest => I::F64Nearest,
520		O::F64Sqrt => I::F64Sqrt,
521		O::F64Add => I::F64Add,
522		O::F64Sub => I::F64Sub,
523		O::F64Mul => I::F64Mul,
524		O::F64Div => I::F64Div,
525		O::F64Min => I::F64Min,
526		O::F64Max => I::F64Max,
527		O::F64Copysign => I::F64Copysign,
528		O::I32WrapI64 => I::I32WrapI64,
529		O::I32TruncF32S => I::I32TruncF32S,
530		O::I32TruncF32U => I::I32TruncF32U,
531		O::I32TruncF64S => I::I32TruncF64S,
532		O::I32TruncF64U => I::I32TruncF64U,
533		O::I64ExtendI32S => I::I64ExtendI32S,
534		O::I64ExtendI32U => I::I64ExtendI32U,
535		O::I64TruncF32S => I::I64TruncF32S,
536		O::I64TruncF32U => I::I64TruncF32U,
537		O::I64TruncF64S => I::I64TruncF64S,
538		O::I64TruncF64U => I::I64TruncF64U,
539		O::F32ConvertI32S => I::F32ConvertI32S,
540		O::F32ConvertI32U => I::F32ConvertI32U,
541		O::F32ConvertI64S => I::F32ConvertI64S,
542		O::F32ConvertI64U => I::F32ConvertI64U,
543		O::F32DemoteF64 => I::F32DemoteF64,
544		O::F64ConvertI32S => I::F64ConvertI32S,
545		O::F64ConvertI32U => I::F64ConvertI32U,
546		O::F64ConvertI64S => I::F64ConvertI64S,
547		O::F64ConvertI64U => I::F64ConvertI64U,
548		O::F64PromoteF32 => I::F64PromoteF32,
549		O::I32ReinterpretF32 => I::I32ReinterpretF32,
550		O::I64ReinterpretF64 => I::I64ReinterpretF64,
551		O::F32ReinterpretI32 => I::F32ReinterpretI32,
552		O::F64ReinterpretI64 => I::F64ReinterpretI64,
553		O::I32Extend8S => I::I32Extend8S,
554		O::I32Extend16S => I::I32Extend16S,
555		O::I64Extend8S => I::I64Extend8S,
556		O::I64Extend16S => I::I64Extend16S,
557		O::I64Extend32S => I::I64Extend32S,
558
559		O::I32TruncSatF32S => I::I32TruncSatF32S,
560		O::I32TruncSatF32U => I::I32TruncSatF32U,
561		O::I32TruncSatF64S => I::I32TruncSatF64S,
562		O::I32TruncSatF64U => I::I32TruncSatF64U,
563		O::I64TruncSatF32S => I::I64TruncSatF32S,
564		O::I64TruncSatF32U => I::I64TruncSatF32U,
565		O::I64TruncSatF64S => I::I64TruncSatF64S,
566		O::I64TruncSatF64U => I::I64TruncSatF64U,
567
568		O::MemoryInit { data_index, mem } => I::MemoryInit { data_index: *data_index, mem: *mem },
569		O::DataDrop { data_index } => I::DataDrop(*data_index),
570		O::MemoryCopy { dst_mem, src_mem } =>
571			I::MemoryCopy { src_mem: *src_mem, dst_mem: *dst_mem },
572		O::MemoryDiscard { mem } => I::MemoryDiscard(*mem),
573		O::MemoryFill { mem, .. } => I::MemoryFill(*mem),
574
575		O::TableInit { elem_index, table } =>
576			I::TableInit { elem_index: *elem_index, table: *table },
577		O::ElemDrop { elem_index } => I::ElemDrop(*elem_index),
578		O::TableCopy { dst_table, src_table } =>
579			I::TableCopy { dst_table: *dst_table, src_table: *src_table },
580		O::TableFill { table } => I::TableFill(*table),
581		O::TableGet { table } => I::TableGet(*table),
582		O::TableSet { table } => I::TableSet(*table),
583		O::TableGrow { table } => I::TableGrow(*table),
584		O::TableSize { table } => I::TableSize(*table),
585
586		O::V128Load { memarg } => I::V128Load(t.translate_memarg(memarg)?),
587		O::V128Load8x8S { memarg } => I::V128Load8x8S(t.translate_memarg(memarg)?),
588		O::V128Load8x8U { memarg } => I::V128Load8x8U(t.translate_memarg(memarg)?),
589		O::V128Load16x4S { memarg } => I::V128Load16x4S(t.translate_memarg(memarg)?),
590		O::V128Load16x4U { memarg } => I::V128Load16x4U(t.translate_memarg(memarg)?),
591		O::V128Load32x2S { memarg } => I::V128Load32x2S(t.translate_memarg(memarg)?),
592		O::V128Load32x2U { memarg } => I::V128Load32x2U(t.translate_memarg(memarg)?),
593		O::V128Load8Splat { memarg } => I::V128Load8Splat(t.translate_memarg(memarg)?),
594		O::V128Load16Splat { memarg } => I::V128Load16Splat(t.translate_memarg(memarg)?),
595		O::V128Load32Splat { memarg } => I::V128Load32Splat(t.translate_memarg(memarg)?),
596		O::V128Load64Splat { memarg } => I::V128Load64Splat(t.translate_memarg(memarg)?),
597		O::V128Load32Zero { memarg } => I::V128Load32Zero(t.translate_memarg(memarg)?),
598		O::V128Load64Zero { memarg } => I::V128Load64Zero(t.translate_memarg(memarg)?),
599		O::V128Store { memarg } => I::V128Store(t.translate_memarg(memarg)?),
600		O::V128Load8Lane { memarg, lane } =>
601			I::V128Load8Lane { memarg: t.translate_memarg(memarg)?, lane: *lane },
602		O::V128Load16Lane { memarg, lane } =>
603			I::V128Load16Lane { memarg: t.translate_memarg(memarg)?, lane: *lane },
604		O::V128Load32Lane { memarg, lane } =>
605			I::V128Load32Lane { memarg: t.translate_memarg(memarg)?, lane: *lane },
606		O::V128Load64Lane { memarg, lane } =>
607			I::V128Load64Lane { memarg: t.translate_memarg(memarg)?, lane: *lane },
608		O::V128Store8Lane { memarg, lane } =>
609			I::V128Store8Lane { memarg: t.translate_memarg(memarg)?, lane: *lane },
610		O::V128Store16Lane { memarg, lane } =>
611			I::V128Store16Lane { memarg: t.translate_memarg(memarg)?, lane: *lane },
612		O::V128Store32Lane { memarg, lane } =>
613			I::V128Store32Lane { memarg: t.translate_memarg(memarg)?, lane: *lane },
614		O::V128Store64Lane { memarg, lane } =>
615			I::V128Store64Lane { memarg: t.translate_memarg(memarg)?, lane: *lane },
616
617		O::V128Const { value } => I::V128Const(value.i128()),
618		O::I8x16Shuffle { lanes } => I::I8x16Shuffle(*lanes),
619		O::I8x16ExtractLaneS { lane } => I::I8x16ExtractLaneS(*lane),
620		O::I8x16ExtractLaneU { lane } => I::I8x16ExtractLaneU(*lane),
621		O::I8x16ReplaceLane { lane } => I::I8x16ReplaceLane(*lane),
622		O::I16x8ExtractLaneS { lane } => I::I16x8ExtractLaneS(*lane),
623		O::I16x8ExtractLaneU { lane } => I::I16x8ExtractLaneU(*lane),
624		O::I16x8ReplaceLane { lane } => I::I16x8ReplaceLane(*lane),
625		O::I32x4ExtractLane { lane } => I::I32x4ExtractLane(*lane),
626		O::I32x4ReplaceLane { lane } => I::I32x4ReplaceLane(*lane),
627		O::I64x2ExtractLane { lane } => I::I64x2ExtractLane(*lane),
628		O::I64x2ReplaceLane { lane } => I::I64x2ReplaceLane(*lane),
629		O::F32x4ExtractLane { lane } => I::F32x4ExtractLane(*lane),
630		O::F32x4ReplaceLane { lane } => I::F32x4ReplaceLane(*lane),
631		O::F64x2ExtractLane { lane } => I::F64x2ExtractLane(*lane),
632		O::F64x2ReplaceLane { lane } => I::F64x2ReplaceLane(*lane),
633
634		O::I8x16Swizzle => I::I8x16Swizzle,
635		O::I8x16Splat => I::I8x16Splat,
636		O::I16x8Splat => I::I16x8Splat,
637		O::I32x4Splat => I::I32x4Splat,
638		O::I64x2Splat => I::I64x2Splat,
639		O::F32x4Splat => I::F32x4Splat,
640		O::F64x2Splat => I::F64x2Splat,
641		O::I8x16Eq => I::I8x16Eq,
642		O::I8x16Ne => I::I8x16Ne,
643		O::I8x16LtS => I::I8x16LtS,
644		O::I8x16LtU => I::I8x16LtU,
645		O::I8x16GtS => I::I8x16GtS,
646		O::I8x16GtU => I::I8x16GtU,
647		O::I8x16LeS => I::I8x16LeS,
648		O::I8x16LeU => I::I8x16LeU,
649		O::I8x16GeS => I::I8x16GeS,
650		O::I8x16GeU => I::I8x16GeU,
651		O::I16x8Eq => I::I16x8Eq,
652		O::I16x8Ne => I::I16x8Ne,
653		O::I16x8LtS => I::I16x8LtS,
654		O::I16x8LtU => I::I16x8LtU,
655		O::I16x8GtS => I::I16x8GtS,
656		O::I16x8GtU => I::I16x8GtU,
657		O::I16x8LeS => I::I16x8LeS,
658		O::I16x8LeU => I::I16x8LeU,
659		O::I16x8GeS => I::I16x8GeS,
660		O::I16x8GeU => I::I16x8GeU,
661		O::I32x4Eq => I::I32x4Eq,
662		O::I32x4Ne => I::I32x4Ne,
663		O::I32x4LtS => I::I32x4LtS,
664		O::I32x4LtU => I::I32x4LtU,
665		O::I32x4GtS => I::I32x4GtS,
666		O::I32x4GtU => I::I32x4GtU,
667		O::I32x4LeS => I::I32x4LeS,
668		O::I32x4LeU => I::I32x4LeU,
669		O::I32x4GeS => I::I32x4GeS,
670		O::I32x4GeU => I::I32x4GeU,
671		O::I64x2Eq => I::I64x2Eq,
672		O::I64x2Ne => I::I64x2Ne,
673		O::I64x2LtS => I::I64x2LtS,
674		O::I64x2GtS => I::I64x2GtS,
675		O::I64x2LeS => I::I64x2LeS,
676		O::I64x2GeS => I::I64x2GeS,
677		O::F32x4Eq => I::F32x4Eq,
678		O::F32x4Ne => I::F32x4Ne,
679		O::F32x4Lt => I::F32x4Lt,
680		O::F32x4Gt => I::F32x4Gt,
681		O::F32x4Le => I::F32x4Le,
682		O::F32x4Ge => I::F32x4Ge,
683		O::F64x2Eq => I::F64x2Eq,
684		O::F64x2Ne => I::F64x2Ne,
685		O::F64x2Lt => I::F64x2Lt,
686		O::F64x2Gt => I::F64x2Gt,
687		O::F64x2Le => I::F64x2Le,
688		O::F64x2Ge => I::F64x2Ge,
689		O::V128Not => I::V128Not,
690		O::V128And => I::V128And,
691		O::V128AndNot => I::V128AndNot,
692		O::V128Or => I::V128Or,
693		O::V128Xor => I::V128Xor,
694		O::V128Bitselect => I::V128Bitselect,
695		O::V128AnyTrue => I::V128AnyTrue,
696		O::I8x16Abs => I::I8x16Abs,
697		O::I8x16Neg => I::I8x16Neg,
698		O::I8x16Popcnt => I::I8x16Popcnt,
699		O::I8x16AllTrue => I::I8x16AllTrue,
700		O::I8x16Bitmask => I::I8x16Bitmask,
701		O::I8x16NarrowI16x8S => I::I8x16NarrowI16x8S,
702		O::I8x16NarrowI16x8U => I::I8x16NarrowI16x8U,
703		O::I8x16Shl => I::I8x16Shl,
704		O::I8x16ShrS => I::I8x16ShrS,
705		O::I8x16ShrU => I::I8x16ShrU,
706		O::I8x16Add => I::I8x16Add,
707		O::I8x16AddSatS => I::I8x16AddSatS,
708		O::I8x16AddSatU => I::I8x16AddSatU,
709		O::I8x16Sub => I::I8x16Sub,
710		O::I8x16SubSatS => I::I8x16SubSatS,
711		O::I8x16SubSatU => I::I8x16SubSatU,
712		O::I8x16MinS => I::I8x16MinS,
713		O::I8x16MinU => I::I8x16MinU,
714		O::I8x16MaxS => I::I8x16MaxS,
715		O::I8x16MaxU => I::I8x16MaxU,
716		O::I8x16AvgrU => I::I8x16AvgrU,
717		O::I16x8ExtAddPairwiseI8x16S => I::I16x8ExtAddPairwiseI8x16S,
718		O::I16x8ExtAddPairwiseI8x16U => I::I16x8ExtAddPairwiseI8x16U,
719		O::I16x8Abs => I::I16x8Abs,
720		O::I16x8Neg => I::I16x8Neg,
721		O::I16x8Q15MulrSatS => I::I16x8Q15MulrSatS,
722		O::I16x8AllTrue => I::I16x8AllTrue,
723		O::I16x8Bitmask => I::I16x8Bitmask,
724		O::I16x8NarrowI32x4S => I::I16x8NarrowI32x4S,
725		O::I16x8NarrowI32x4U => I::I16x8NarrowI32x4U,
726		O::I16x8ExtendLowI8x16S => I::I16x8ExtendLowI8x16S,
727		O::I16x8ExtendHighI8x16S => I::I16x8ExtendHighI8x16S,
728		O::I16x8ExtendLowI8x16U => I::I16x8ExtendLowI8x16U,
729		O::I16x8ExtendHighI8x16U => I::I16x8ExtendHighI8x16U,
730		O::I16x8Shl => I::I16x8Shl,
731		O::I16x8ShrS => I::I16x8ShrS,
732		O::I16x8ShrU => I::I16x8ShrU,
733		O::I16x8Add => I::I16x8Add,
734		O::I16x8AddSatS => I::I16x8AddSatS,
735		O::I16x8AddSatU => I::I16x8AddSatU,
736		O::I16x8Sub => I::I16x8Sub,
737		O::I16x8SubSatS => I::I16x8SubSatS,
738		O::I16x8SubSatU => I::I16x8SubSatU,
739		O::I16x8Mul => I::I16x8Mul,
740		O::I16x8MinS => I::I16x8MinS,
741		O::I16x8MinU => I::I16x8MinU,
742		O::I16x8MaxS => I::I16x8MaxS,
743		O::I16x8MaxU => I::I16x8MaxU,
744		O::I16x8AvgrU => I::I16x8AvgrU,
745		O::I16x8ExtMulLowI8x16S => I::I16x8ExtMulLowI8x16S,
746		O::I16x8ExtMulHighI8x16S => I::I16x8ExtMulHighI8x16S,
747		O::I16x8ExtMulLowI8x16U => I::I16x8ExtMulLowI8x16U,
748		O::I16x8ExtMulHighI8x16U => I::I16x8ExtMulHighI8x16U,
749		O::I32x4ExtAddPairwiseI16x8S => I::I32x4ExtAddPairwiseI16x8S,
750		O::I32x4ExtAddPairwiseI16x8U => I::I32x4ExtAddPairwiseI16x8U,
751		O::I32x4Abs => I::I32x4Abs,
752		O::I32x4Neg => I::I32x4Neg,
753		O::I32x4AllTrue => I::I32x4AllTrue,
754		O::I32x4Bitmask => I::I32x4Bitmask,
755		O::I32x4ExtendLowI16x8S => I::I32x4ExtendLowI16x8S,
756		O::I32x4ExtendHighI16x8S => I::I32x4ExtendHighI16x8S,
757		O::I32x4ExtendLowI16x8U => I::I32x4ExtendLowI16x8U,
758		O::I32x4ExtendHighI16x8U => I::I32x4ExtendHighI16x8U,
759		O::I32x4Shl => I::I32x4Shl,
760		O::I32x4ShrS => I::I32x4ShrS,
761		O::I32x4ShrU => I::I32x4ShrU,
762		O::I32x4Add => I::I32x4Add,
763		O::I32x4Sub => I::I32x4Sub,
764		O::I32x4Mul => I::I32x4Mul,
765		O::I32x4MinS => I::I32x4MinS,
766		O::I32x4MinU => I::I32x4MinU,
767		O::I32x4MaxS => I::I32x4MaxS,
768		O::I32x4MaxU => I::I32x4MaxU,
769		O::I32x4DotI16x8S => I::I32x4DotI16x8S,
770		O::I32x4ExtMulLowI16x8S => I::I32x4ExtMulLowI16x8S,
771		O::I32x4ExtMulHighI16x8S => I::I32x4ExtMulHighI16x8S,
772		O::I32x4ExtMulLowI16x8U => I::I32x4ExtMulLowI16x8U,
773		O::I32x4ExtMulHighI16x8U => I::I32x4ExtMulHighI16x8U,
774		O::I64x2Abs => I::I64x2Abs,
775		O::I64x2Neg => I::I64x2Neg,
776		O::I64x2AllTrue => I::I64x2AllTrue,
777		O::I64x2Bitmask => I::I64x2Bitmask,
778		O::I64x2ExtendLowI32x4S => I::I64x2ExtendLowI32x4S,
779		O::I64x2ExtendHighI32x4S => I::I64x2ExtendHighI32x4S,
780		O::I64x2ExtendLowI32x4U => I::I64x2ExtendLowI32x4U,
781		O::I64x2ExtendHighI32x4U => I::I64x2ExtendHighI32x4U,
782		O::I64x2Shl => I::I64x2Shl,
783		O::I64x2ShrS => I::I64x2ShrS,
784		O::I64x2ShrU => I::I64x2ShrU,
785		O::I64x2Add => I::I64x2Add,
786		O::I64x2Sub => I::I64x2Sub,
787		O::I64x2Mul => I::I64x2Mul,
788		O::I64x2ExtMulLowI32x4S => I::I64x2ExtMulLowI32x4S,
789		O::I64x2ExtMulHighI32x4S => I::I64x2ExtMulHighI32x4S,
790		O::I64x2ExtMulLowI32x4U => I::I64x2ExtMulLowI32x4U,
791		O::I64x2ExtMulHighI32x4U => I::I64x2ExtMulHighI32x4U,
792		O::F32x4Ceil => I::F32x4Ceil,
793		O::F32x4Floor => I::F32x4Floor,
794		O::F32x4Trunc => I::F32x4Trunc,
795		O::F32x4Nearest => I::F32x4Nearest,
796		O::F32x4Abs => I::F32x4Abs,
797		O::F32x4Neg => I::F32x4Neg,
798		O::F32x4Sqrt => I::F32x4Sqrt,
799		O::F32x4Add => I::F32x4Add,
800		O::F32x4Sub => I::F32x4Sub,
801		O::F32x4Mul => I::F32x4Mul,
802		O::F32x4Div => I::F32x4Div,
803		O::F32x4Min => I::F32x4Min,
804		O::F32x4Max => I::F32x4Max,
805		O::F32x4PMin => I::F32x4PMin,
806		O::F32x4PMax => I::F32x4PMax,
807		O::F64x2Ceil => I::F64x2Ceil,
808		O::F64x2Floor => I::F64x2Floor,
809		O::F64x2Trunc => I::F64x2Trunc,
810		O::F64x2Nearest => I::F64x2Nearest,
811		O::F64x2Abs => I::F64x2Abs,
812		O::F64x2Neg => I::F64x2Neg,
813		O::F64x2Sqrt => I::F64x2Sqrt,
814		O::F64x2Add => I::F64x2Add,
815		O::F64x2Sub => I::F64x2Sub,
816		O::F64x2Mul => I::F64x2Mul,
817		O::F64x2Div => I::F64x2Div,
818		O::F64x2Min => I::F64x2Min,
819		O::F64x2Max => I::F64x2Max,
820		O::F64x2PMin => I::F64x2PMin,
821		O::F64x2PMax => I::F64x2PMax,
822		O::I32x4TruncSatF32x4S => I::I32x4TruncSatF32x4S,
823		O::I32x4TruncSatF32x4U => I::I32x4TruncSatF32x4U,
824		O::F32x4ConvertI32x4S => I::F32x4ConvertI32x4S,
825		O::F32x4ConvertI32x4U => I::F32x4ConvertI32x4U,
826		O::I32x4TruncSatF64x2SZero => I::I32x4TruncSatF64x2SZero,
827		O::I32x4TruncSatF64x2UZero => I::I32x4TruncSatF64x2UZero,
828		O::F64x2ConvertLowI32x4S => I::F64x2ConvertLowI32x4S,
829		O::F64x2ConvertLowI32x4U => I::F64x2ConvertLowI32x4U,
830		O::F32x4DemoteF64x2Zero => I::F32x4DemoteF64x2Zero,
831		O::F64x2PromoteLowF32x4 => I::F64x2PromoteLowF32x4,
832		O::I8x16RelaxedSwizzle => I::I8x16RelaxedSwizzle,
833		O::I32x4RelaxedTruncF32x4S => I::I32x4RelaxedTruncF32x4S,
834		O::I32x4RelaxedTruncF32x4U => I::I32x4RelaxedTruncF32x4U,
835		O::I32x4RelaxedTruncF64x2SZero => I::I32x4RelaxedTruncF64x2SZero,
836		O::I32x4RelaxedTruncF64x2UZero => I::I32x4RelaxedTruncF64x2UZero,
837		O::F32x4RelaxedMadd => I::F32x4RelaxedMadd,
838		O::F32x4RelaxedNmadd => I::F32x4RelaxedNmadd,
839		O::F64x2RelaxedMadd => I::F64x2RelaxedMadd,
840		O::F64x2RelaxedNmadd => I::F64x2RelaxedNmadd,
841		O::I8x16RelaxedLaneselect => I::I8x16RelaxedLaneselect,
842		O::I16x8RelaxedLaneselect => I::I16x8RelaxedLaneselect,
843		O::I32x4RelaxedLaneselect => I::I32x4RelaxedLaneselect,
844		O::I64x2RelaxedLaneselect => I::I64x2RelaxedLaneselect,
845		O::F32x4RelaxedMin => I::F32x4RelaxedMin,
846		O::F32x4RelaxedMax => I::F32x4RelaxedMax,
847		O::F64x2RelaxedMin => I::F64x2RelaxedMin,
848		O::F64x2RelaxedMax => I::F64x2RelaxedMax,
849		O::I16x8RelaxedQ15mulrS => I::I16x8RelaxedQ15mulrS,
850		O::I16x8RelaxedDotI8x16I7x16S => I::I16x8RelaxedDotI8x16I7x16S,
851		O::I32x4RelaxedDotI8x16I7x16AddS => I::I32x4RelaxedDotI8x16I7x16AddS,
852
853		O::CallRef { type_index } => I::CallRef(*type_index),
854		O::ReturnCallRef { type_index } => I::ReturnCallRef(*type_index),
855		O::RefAsNonNull => I::RefAsNonNull,
856		O::BrOnNull { relative_depth } => I::BrOnNull(*relative_depth),
857		O::BrOnNonNull { relative_depth } => I::BrOnNonNull(*relative_depth),
858
859		O::MemoryAtomicNotify { memarg } => I::MemoryAtomicNotify(t.translate_memarg(memarg)?),
860		O::MemoryAtomicWait32 { memarg } => I::MemoryAtomicWait32(t.translate_memarg(memarg)?),
861		O::MemoryAtomicWait64 { memarg } => I::MemoryAtomicWait64(t.translate_memarg(memarg)?),
862		O::I32AtomicLoad { memarg } => I::I32AtomicLoad(t.translate_memarg(memarg)?),
863		O::I32AtomicLoad8U { memarg } => I::I32AtomicLoad8U(t.translate_memarg(memarg)?),
864		O::I32AtomicLoad16U { memarg } => I::I32AtomicLoad16U(t.translate_memarg(memarg)?),
865		O::I64AtomicLoad { memarg } => I::I64AtomicLoad(t.translate_memarg(memarg)?),
866		O::I64AtomicLoad8U { memarg } => I::I64AtomicLoad8U(t.translate_memarg(memarg)?),
867		O::I64AtomicLoad16U { memarg } => I::I64AtomicLoad16U(t.translate_memarg(memarg)?),
868		O::I64AtomicLoad32U { memarg } => I::I64AtomicLoad32U(t.translate_memarg(memarg)?),
869		O::I32AtomicStore { memarg } => I::I32AtomicStore(t.translate_memarg(memarg)?),
870		O::I64AtomicStore { memarg } => I::I64AtomicStore(t.translate_memarg(memarg)?),
871		O::I32AtomicStore8 { memarg } => I::I32AtomicStore8(t.translate_memarg(memarg)?),
872		O::I32AtomicStore16 { memarg } => I::I32AtomicStore16(t.translate_memarg(memarg)?),
873		O::I64AtomicStore8 { memarg } => I::I64AtomicStore8(t.translate_memarg(memarg)?),
874		O::I64AtomicStore16 { memarg } => I::I64AtomicStore16(t.translate_memarg(memarg)?),
875		O::I64AtomicStore32 { memarg } => I::I64AtomicStore32(t.translate_memarg(memarg)?),
876		O::I32AtomicRmwAdd { memarg } => I::I32AtomicRmwAdd(t.translate_memarg(memarg)?),
877		O::I64AtomicRmwAdd { memarg } => I::I64AtomicRmwAdd(t.translate_memarg(memarg)?),
878		O::I32AtomicRmw8AddU { memarg } => I::I32AtomicRmw8AddU(t.translate_memarg(memarg)?),
879		O::I32AtomicRmw16AddU { memarg } => I::I32AtomicRmw16AddU(t.translate_memarg(memarg)?),
880		O::I64AtomicRmw8AddU { memarg } => I::I64AtomicRmw8AddU(t.translate_memarg(memarg)?),
881		O::I64AtomicRmw16AddU { memarg } => I::I64AtomicRmw16AddU(t.translate_memarg(memarg)?),
882		O::I64AtomicRmw32AddU { memarg } => I::I64AtomicRmw32AddU(t.translate_memarg(memarg)?),
883		O::I32AtomicRmwSub { memarg } => I::I32AtomicRmwSub(t.translate_memarg(memarg)?),
884		O::I64AtomicRmwSub { memarg } => I::I64AtomicRmwSub(t.translate_memarg(memarg)?),
885		O::I32AtomicRmw8SubU { memarg } => I::I32AtomicRmw8SubU(t.translate_memarg(memarg)?),
886		O::I32AtomicRmw16SubU { memarg } => I::I32AtomicRmw16SubU(t.translate_memarg(memarg)?),
887		O::I64AtomicRmw8SubU { memarg } => I::I64AtomicRmw8SubU(t.translate_memarg(memarg)?),
888		O::I64AtomicRmw16SubU { memarg } => I::I64AtomicRmw16SubU(t.translate_memarg(memarg)?),
889		O::I64AtomicRmw32SubU { memarg } => I::I64AtomicRmw32SubU(t.translate_memarg(memarg)?),
890		O::I32AtomicRmwAnd { memarg } => I::I32AtomicRmwAnd(t.translate_memarg(memarg)?),
891		O::I64AtomicRmwAnd { memarg } => I::I64AtomicRmwAnd(t.translate_memarg(memarg)?),
892		O::I32AtomicRmw8AndU { memarg } => I::I32AtomicRmw8AndU(t.translate_memarg(memarg)?),
893		O::I32AtomicRmw16AndU { memarg } => I::I32AtomicRmw16AndU(t.translate_memarg(memarg)?),
894		O::I64AtomicRmw8AndU { memarg } => I::I64AtomicRmw8AndU(t.translate_memarg(memarg)?),
895		O::I64AtomicRmw16AndU { memarg } => I::I64AtomicRmw16AndU(t.translate_memarg(memarg)?),
896		O::I64AtomicRmw32AndU { memarg } => I::I64AtomicRmw32AndU(t.translate_memarg(memarg)?),
897		O::I32AtomicRmwOr { memarg } => I::I32AtomicRmwOr(t.translate_memarg(memarg)?),
898		O::I64AtomicRmwOr { memarg } => I::I64AtomicRmwOr(t.translate_memarg(memarg)?),
899		O::I32AtomicRmw8OrU { memarg } => I::I32AtomicRmw8OrU(t.translate_memarg(memarg)?),
900		O::I32AtomicRmw16OrU { memarg } => I::I32AtomicRmw16OrU(t.translate_memarg(memarg)?),
901		O::I64AtomicRmw8OrU { memarg } => I::I64AtomicRmw8OrU(t.translate_memarg(memarg)?),
902		O::I64AtomicRmw16OrU { memarg } => I::I64AtomicRmw16OrU(t.translate_memarg(memarg)?),
903		O::I64AtomicRmw32OrU { memarg } => I::I64AtomicRmw32OrU(t.translate_memarg(memarg)?),
904		O::I32AtomicRmwXor { memarg } => I::I32AtomicRmwXor(t.translate_memarg(memarg)?),
905		O::I64AtomicRmwXor { memarg } => I::I64AtomicRmwXor(t.translate_memarg(memarg)?),
906		O::I32AtomicRmw8XorU { memarg } => I::I32AtomicRmw8XorU(t.translate_memarg(memarg)?),
907		O::I32AtomicRmw16XorU { memarg } => I::I32AtomicRmw16XorU(t.translate_memarg(memarg)?),
908		O::I64AtomicRmw8XorU { memarg } => I::I64AtomicRmw8XorU(t.translate_memarg(memarg)?),
909		O::I64AtomicRmw16XorU { memarg } => I::I64AtomicRmw16XorU(t.translate_memarg(memarg)?),
910		O::I64AtomicRmw32XorU { memarg } => I::I64AtomicRmw32XorU(t.translate_memarg(memarg)?),
911		O::I32AtomicRmwXchg { memarg } => I::I32AtomicRmwXchg(t.translate_memarg(memarg)?),
912		O::I64AtomicRmwXchg { memarg } => I::I64AtomicRmwXchg(t.translate_memarg(memarg)?),
913		O::I32AtomicRmw8XchgU { memarg } => I::I32AtomicRmw8XchgU(t.translate_memarg(memarg)?),
914		O::I32AtomicRmw16XchgU { memarg } => I::I32AtomicRmw16XchgU(t.translate_memarg(memarg)?),
915		O::I64AtomicRmw8XchgU { memarg } => I::I64AtomicRmw8XchgU(t.translate_memarg(memarg)?),
916		O::I64AtomicRmw16XchgU { memarg } => I::I64AtomicRmw16XchgU(t.translate_memarg(memarg)?),
917		O::I64AtomicRmw32XchgU { memarg } => I::I64AtomicRmw32XchgU(t.translate_memarg(memarg)?),
918		O::I32AtomicRmwCmpxchg { memarg } => I::I32AtomicRmwCmpxchg(t.translate_memarg(memarg)?),
919		O::I64AtomicRmwCmpxchg { memarg } => I::I64AtomicRmwCmpxchg(t.translate_memarg(memarg)?),
920		O::I32AtomicRmw8CmpxchgU { memarg } =>
921			I::I32AtomicRmw8CmpxchgU(t.translate_memarg(memarg)?),
922		O::I32AtomicRmw16CmpxchgU { memarg } =>
923			I::I32AtomicRmw16CmpxchgU(t.translate_memarg(memarg)?),
924		O::I64AtomicRmw8CmpxchgU { memarg } =>
925			I::I64AtomicRmw8CmpxchgU(t.translate_memarg(memarg)?),
926		O::I64AtomicRmw16CmpxchgU { memarg } =>
927			I::I64AtomicRmw16CmpxchgU(t.translate_memarg(memarg)?),
928		O::I64AtomicRmw32CmpxchgU { memarg } =>
929			I::I64AtomicRmw32CmpxchgU(t.translate_memarg(memarg)?),
930		O::AtomicFence => I::AtomicFence,
931	})
932}
933
934pub fn block_type(t: &mut dyn Translator, ty: &wasmparser::BlockType) -> Result<BlockType> {
935	match ty {
936		wasmparser::BlockType::Empty => Ok(BlockType::Empty),
937		wasmparser::BlockType::Type(ty) => Ok(BlockType::Result(t.translate_ty(ty)?)),
938		wasmparser::BlockType::FuncType(f) => Ok(BlockType::FunctionType(*f)),
939	}
940}
941
942pub fn memarg(_t: &mut dyn Translator, memarg: &wasmparser::MemArg) -> Result<MemArg> {
943	Ok(MemArg { offset: memarg.offset, align: memarg.align.into(), memory_index: memarg.memory })
944}
945
946#[allow(dead_code)]
947pub fn data(t: &mut dyn Translator, data: wasmparser::Data<'_>, s: &mut DataSection) -> Result<()> {
948	let offset;
949	let mode = match &data.kind {
950		DataKind::Active { memory_index, offset_expr } => {
951			offset = t.translate_const_expr(
952				offset_expr,
953				&wasmparser::ValType::I32,
954				ConstExprKind::DataOffset,
955			)?;
956			DataSegmentMode::Active { memory_index: *memory_index, offset: &offset }
957		},
958		DataKind::Passive => DataSegmentMode::Passive,
959	};
960	s.segment(DataSegment { mode, data: data.data.iter().copied() });
961	Ok(())
962}
963
964pub fn code(t: &mut dyn Translator, body: FunctionBody<'_>, s: &mut CodeSection) -> Result<()> {
965	let locals = body
966		.get_locals_reader()?
967		.into_iter()
968		.map(|local| {
969			let (cnt, ty) = local?;
970			Ok((cnt, t.translate_ty(&ty)?))
971		})
972		.collect::<Result<Vec<_>>>()?;
973	let mut func = Function::new(locals);
974
975	let reader = body.get_operators_reader()?;
976	for op in reader {
977		let op = op?;
978		func.instruction(&t.translate_op(&op)?);
979	}
980	s.function(&func);
981	Ok(())
982}