use super::{FuncBuilder, FuncValidator, TranslationError};
use wasmparser::{BinaryReaderError, VisitOperator};
macro_rules! for_each_supported_operator {
($mac:ident) => {
$mac! {
fn visit_unreachable() => fn translate_unreachable
fn visit_nop() => fn translate_nop
fn visit_block(ty: wasmparser::BlockType) => fn translate_block
fn visit_loop(ty: wasmparser::BlockType) => fn translate_loop
fn visit_if(ty: wasmparser::BlockType) => fn translate_if
fn visit_else() => fn translate_else
fn visit_end() => fn translate_end
fn visit_br(relative_depth: u32) => fn translate_br
fn visit_br_if(relative_depth: u32) => fn translate_br_if
fn visit_return() => fn translate_return
fn visit_call(function_index: u32) => fn translate_call
fn visit_call_indirect(index: u32, table_index: u32, table_byte: u8) => fn translate_call_indirect
fn visit_drop() => fn translate_drop
fn visit_select() => fn translate_select
fn visit_typed_select(ty: wasmparser::ValType) => fn translate_typed_select
fn visit_ref_null(ty: wasmparser::ValType) => fn translate_ref_null
fn visit_ref_is_null() => fn translate_ref_is_null
fn visit_ref_func(func_index: u32) => fn translate_ref_func
fn visit_local_get(local_index: u32) => fn translate_local_get
fn visit_local_set(local_index: u32) => fn translate_local_set
fn visit_local_tee(local_index: u32) => fn translate_local_tee
fn visit_global_get(global_index: u32) => fn translate_global_get
fn visit_global_set(global_index: u32) => fn translate_global_set
fn visit_i32_load(memarg: wasmparser::MemArg) => fn translate_i32_load
fn visit_i64_load(memarg: wasmparser::MemArg) => fn translate_i64_load
fn visit_f32_load(memarg: wasmparser::MemArg) => fn translate_f32_load
fn visit_f64_load(memarg: wasmparser::MemArg) => fn translate_f64_load
fn visit_i32_load8_s(memarg: wasmparser::MemArg) => fn translate_i32_load8_s
fn visit_i32_load8_u(memarg: wasmparser::MemArg) => fn translate_i32_load8_u
fn visit_i32_load16_s(memarg: wasmparser::MemArg) => fn translate_i32_load16_s
fn visit_i32_load16_u(memarg: wasmparser::MemArg) => fn translate_i32_load16_u
fn visit_i64_load8_s(memarg: wasmparser::MemArg) => fn translate_i64_load8_s
fn visit_i64_load8_u(memarg: wasmparser::MemArg) => fn translate_i64_load8_u
fn visit_i64_load16_s(memarg: wasmparser::MemArg) => fn translate_i64_load16_s
fn visit_i64_load16_u(memarg: wasmparser::MemArg) => fn translate_i64_load16_u
fn visit_i64_load32_s(memarg: wasmparser::MemArg) => fn translate_i64_load32_s
fn visit_i64_load32_u(memarg: wasmparser::MemArg) => fn translate_i64_load32_u
fn visit_i32_store(memarg: wasmparser::MemArg) => fn translate_i32_store
fn visit_i64_store(memarg: wasmparser::MemArg) => fn translate_i64_store
fn visit_f32_store(memarg: wasmparser::MemArg) => fn translate_f32_store
fn visit_f64_store(memarg: wasmparser::MemArg) => fn translate_f64_store
fn visit_i32_store8(memarg: wasmparser::MemArg) => fn translate_i32_store8
fn visit_i32_store16(memarg: wasmparser::MemArg) => fn translate_i32_store16
fn visit_i64_store8(memarg: wasmparser::MemArg) => fn translate_i64_store8
fn visit_i64_store16(memarg: wasmparser::MemArg) => fn translate_i64_store16
fn visit_i64_store32(memarg: wasmparser::MemArg) => fn translate_i64_store32
fn visit_memory_size(mem: u32, mem_byte: u8) => fn translate_memory_size
fn visit_memory_grow(mem: u32, mem_byte: u8) => fn translate_memory_grow
fn visit_memory_copy(dst_mem: u32, src_mem: u32) => fn translate_memory_copy
fn visit_memory_fill(mem: u32) => fn translate_memory_fill
fn visit_memory_init(seg: u32, mem: u32) => fn translate_memory_init
fn visit_data_drop(seg: u32) => fn translate_data_drop
fn visit_table_size(table: u32) => fn translate_table_size
fn visit_table_grow(table: u32) => fn translate_table_grow
fn visit_table_copy(dst_table: u32, src_table: u32) => fn translate_table_copy
fn visit_table_fill(table: u32) => fn translate_table_fill
fn visit_table_get(table: u32) => fn translate_table_get
fn visit_table_set(table: u32) => fn translate_table_set
fn visit_table_init(seg: u32, table: u32) => fn translate_table_init
fn visit_elem_drop(seg: u32) => fn translate_elem_drop
fn visit_i32_const(value: i32) => fn translate_i32_const
fn visit_i64_const(value: i64) => fn translate_i64_const
fn visit_f32_const(value: wasmparser::Ieee32) => fn translate_f32_const
fn visit_f64_const(value: wasmparser::Ieee64) => fn translate_f64_const
fn visit_i32_eqz() => fn translate_i32_eqz
fn visit_i32_eq() => fn translate_i32_eq
fn visit_i32_ne() => fn translate_i32_ne
fn visit_i32_lt_s() => fn translate_i32_lt_s
fn visit_i32_lt_u() => fn translate_i32_lt_u
fn visit_i32_gt_s() => fn translate_i32_gt_s
fn visit_i32_gt_u() => fn translate_i32_gt_u
fn visit_i32_le_s() => fn translate_i32_le_s
fn visit_i32_le_u() => fn translate_i32_le_u
fn visit_i32_ge_s() => fn translate_i32_ge_s
fn visit_i32_ge_u() => fn translate_i32_ge_u
fn visit_i64_eqz() => fn translate_i64_eqz
fn visit_i64_eq() => fn translate_i64_eq
fn visit_i64_ne() => fn translate_i64_ne
fn visit_i64_lt_s() => fn translate_i64_lt_s
fn visit_i64_lt_u() => fn translate_i64_lt_u
fn visit_i64_gt_s() => fn translate_i64_gt_s
fn visit_i64_gt_u() => fn translate_i64_gt_u
fn visit_i64_le_s() => fn translate_i64_le_s
fn visit_i64_le_u() => fn translate_i64_le_u
fn visit_i64_ge_s() => fn translate_i64_ge_s
fn visit_i64_ge_u() => fn translate_i64_ge_u
fn visit_f32_eq() => fn translate_f32_eq
fn visit_f32_ne() => fn translate_f32_ne
fn visit_f32_lt() => fn translate_f32_lt
fn visit_f32_gt() => fn translate_f32_gt
fn visit_f32_le() => fn translate_f32_le
fn visit_f32_ge() => fn translate_f32_ge
fn visit_f64_eq() => fn translate_f64_eq
fn visit_f64_ne() => fn translate_f64_ne
fn visit_f64_lt() => fn translate_f64_lt
fn visit_f64_gt() => fn translate_f64_gt
fn visit_f64_le() => fn translate_f64_le
fn visit_f64_ge() => fn translate_f64_ge
fn visit_i32_clz() => fn translate_i32_clz
fn visit_i32_ctz() => fn translate_i32_ctz
fn visit_i32_popcnt() => fn translate_i32_popcnt
fn visit_i32_add() => fn translate_i32_add
fn visit_i32_sub() => fn translate_i32_sub
fn visit_i32_mul() => fn translate_i32_mul
fn visit_i32_div_s() => fn translate_i32_div_s
fn visit_i32_div_u() => fn translate_i32_div_u
fn visit_i32_rem_s() => fn translate_i32_rem_s
fn visit_i32_rem_u() => fn translate_i32_rem_u
fn visit_i32_and() => fn translate_i32_and
fn visit_i32_or() => fn translate_i32_or
fn visit_i32_xor() => fn translate_i32_xor
fn visit_i32_shl() => fn translate_i32_shl
fn visit_i32_shr_s() => fn translate_i32_shr_s
fn visit_i32_shr_u() => fn translate_i32_shr_u
fn visit_i32_rotl() => fn translate_i32_rotl
fn visit_i32_rotr() => fn translate_i32_rotr
fn visit_i64_clz() => fn translate_i64_clz
fn visit_i64_ctz() => fn translate_i64_ctz
fn visit_i64_popcnt() => fn translate_i64_popcnt
fn visit_i64_add() => fn translate_i64_add
fn visit_i64_sub() => fn translate_i64_sub
fn visit_i64_mul() => fn translate_i64_mul
fn visit_i64_div_s() => fn translate_i64_div_s
fn visit_i64_div_u() => fn translate_i64_div_u
fn visit_i64_rem_s() => fn translate_i64_rem_s
fn visit_i64_rem_u() => fn translate_i64_rem_u
fn visit_i64_and() => fn translate_i64_and
fn visit_i64_or() => fn translate_i64_or
fn visit_i64_xor() => fn translate_i64_xor
fn visit_i64_shl() => fn translate_i64_shl
fn visit_i64_shr_s() => fn translate_i64_shr_s
fn visit_i64_shr_u() => fn translate_i64_shr_u
fn visit_i64_rotl() => fn translate_i64_rotl
fn visit_i64_rotr() => fn translate_i64_rotr
fn visit_f32_abs() => fn translate_f32_abs
fn visit_f32_neg() => fn translate_f32_neg
fn visit_f32_ceil() => fn translate_f32_ceil
fn visit_f32_floor() => fn translate_f32_floor
fn visit_f32_trunc() => fn translate_f32_trunc
fn visit_f32_nearest() => fn translate_f32_nearest
fn visit_f32_sqrt() => fn translate_f32_sqrt
fn visit_f32_add() => fn translate_f32_add
fn visit_f32_sub() => fn translate_f32_sub
fn visit_f32_mul() => fn translate_f32_mul
fn visit_f32_div() => fn translate_f32_div
fn visit_f32_min() => fn translate_f32_min
fn visit_f32_max() => fn translate_f32_max
fn visit_f32_copysign() => fn translate_f32_copysign
fn visit_f64_abs() => fn translate_f64_abs
fn visit_f64_neg() => fn translate_f64_neg
fn visit_f64_ceil() => fn translate_f64_ceil
fn visit_f64_floor() => fn translate_f64_floor
fn visit_f64_trunc() => fn translate_f64_trunc
fn visit_f64_nearest() => fn translate_f64_nearest
fn visit_f64_sqrt() => fn translate_f64_sqrt
fn visit_f64_add() => fn translate_f64_add
fn visit_f64_sub() => fn translate_f64_sub
fn visit_f64_mul() => fn translate_f64_mul
fn visit_f64_div() => fn translate_f64_div
fn visit_f64_min() => fn translate_f64_min
fn visit_f64_max() => fn translate_f64_max
fn visit_f64_copysign() => fn translate_f64_copysign
fn visit_i32_wrap_i64() => fn translate_i32_wrap_i64
fn visit_i32_trunc_f32_s() => fn translate_i32_trunc_f32_s
fn visit_i32_trunc_f32_u() => fn translate_i32_trunc_f32_u
fn visit_i32_trunc_f64_s() => fn translate_i32_trunc_f64_s
fn visit_i32_trunc_f64_u() => fn translate_i32_trunc_f64_u
fn visit_i64_extend_i32_s() => fn translate_i64_extend_i32_s
fn visit_i64_extend_i32_u() => fn translate_i64_extend_i32_u
fn visit_i64_trunc_f32_s() => fn translate_i64_trunc_f32_s
fn visit_i64_trunc_f32_u() => fn translate_i64_trunc_f32_u
fn visit_i64_trunc_f64_s() => fn translate_i64_trunc_f64_s
fn visit_i64_trunc_f64_u() => fn translate_i64_trunc_f64_u
fn visit_f32_convert_i32_s() => fn translate_f32_convert_i32_s
fn visit_f32_convert_i32_u() => fn translate_f32_convert_i32_u
fn visit_f32_convert_i64_s() => fn translate_f32_convert_i64_s
fn visit_f32_convert_i64_u() => fn translate_f32_convert_i64_u
fn visit_f32_demote_f64() => fn translate_f32_demote_f64
fn visit_f64_convert_i32_s() => fn translate_f64_convert_i32_s
fn visit_f64_convert_i32_u() => fn translate_f64_convert_i32_u
fn visit_f64_convert_i64_s() => fn translate_f64_convert_i64_s
fn visit_f64_convert_i64_u() => fn translate_f64_convert_i64_u
fn visit_f64_promote_f32() => fn translate_f64_promote_f32
fn visit_i32_reinterpret_f32() => fn translate_i32_reinterpret_f32
fn visit_i64_reinterpret_f64() => fn translate_i64_reinterpret_f64
fn visit_f32_reinterpret_i32() => fn translate_f32_reinterpret_i32
fn visit_f64_reinterpret_i64() => fn translate_f64_reinterpret_i64
fn visit_i32_extend8_s() => fn translate_i32_extend8_s
fn visit_i32_extend16_s() => fn translate_i32_extend16_s
fn visit_i64_extend8_s() => fn translate_i64_extend8_s
fn visit_i64_extend16_s() => fn translate_i64_extend16_s
fn visit_i64_extend32_s() => fn translate_i64_extend32_s
fn visit_i32_trunc_sat_f32_s() => fn translate_i32_trunc_sat_f32_s
fn visit_i32_trunc_sat_f32_u() => fn translate_i32_trunc_sat_f32_u
fn visit_i32_trunc_sat_f64_s() => fn translate_i32_trunc_sat_f64_s
fn visit_i32_trunc_sat_f64_u() => fn translate_i32_trunc_sat_f64_u
fn visit_i64_trunc_sat_f32_s() => fn translate_i64_trunc_sat_f32_s
fn visit_i64_trunc_sat_f32_u() => fn translate_i64_trunc_sat_f32_u
fn visit_i64_trunc_sat_f64_s() => fn translate_i64_trunc_sat_f64_s
fn visit_i64_trunc_sat_f64_u() => fn translate_i64_trunc_sat_f64_u
}
}
}
impl<'parser> FuncBuilder<'parser> {
fn validate_then_translate<V, F>(
&mut self,
validate: V,
translator: F,
) -> Result<(), TranslationError>
where
V: FnOnce(&mut FuncValidator) -> Result<(), BinaryReaderError>,
F: FnOnce(&mut Self) -> Result<(), TranslationError>,
{
validate(&mut self.validator)?;
translator(self)?;
Ok(())
}
}
macro_rules! define_supported_visit_operator {
($( fn $visit:ident $(( $($arg:ident: $argty:ty),* ))? => fn $translate:ident)*) => {
$(
fn $visit(&mut self, offset: usize $($(,$arg: $argty)*)?) -> Self::Output {
self.validate_then_translate(
|v| v.$visit(offset $($(,$arg)*)?),
|this| {
this.$translate($($($arg),*)?)
},
)
}
)*
};
}
macro_rules! define_unsupported_visit_operator {
( @mvp $op:ident $({ $($arg:ident: $argty:ty),* })? => $visit:ident $($rest:tt)* ) => {
define_unsupported_visit_operator!($($rest)*);
};
( @sign_ext_ops $op:ident $({ $($arg:ident: $argty:ty),* })? => $visit:ident $($rest:tt)* ) => {
define_unsupported_visit_operator!($($rest)*);
};
( @non_trapping_f2i_conversions $op:ident $({ $($arg:ident: $argty:ty),* })? => $visit:ident $($rest:tt)* ) => {
define_unsupported_visit_operator!($($rest)*);
};
( @bulk_memory $op:ident $({ $($arg:ident: $argty:ty),* })? => $visit:ident $($rest:tt)* ) => {
define_unsupported_visit_operator!($($rest)*);
};
( @reference_types $op:ident $({ $($arg:ident: $argty:ty),* })? => $visit:ident $($rest:tt)* ) => {
define_unsupported_visit_operator!($($rest)*);
};
( @$proposal:ident $op:ident $({ $($arg:ident: $argty:ty),* })? => $visit:ident $($rest:tt)* ) => {
fn $visit(&mut self, offset: usize $($(,$arg: $argty)*)?) -> Self::Output {
self.validator.$visit(offset $($(,$arg)*)?).map_err(::core::convert::Into::into)
}
define_unsupported_visit_operator!($($rest)*);
};
() => {};
}
impl<'a> VisitOperator<'a> for FuncBuilder<'a> {
type Output = Result<(), TranslationError>;
for_each_supported_operator!(define_supported_visit_operator);
wasmparser::for_each_operator!(define_unsupported_visit_operator);
fn visit_br_table(&mut self, offset: usize, table: wasmparser::BrTable<'a>) -> Self::Output {
let table_cloned = table.clone();
self.validate_then_translate(
|v| v.visit_br_table(offset, table_cloned),
|this| this.translate_br_table(table),
)
}
}