diff --git a/src/backend/binaryen.rs b/src/backend/binaryen.rs deleted file mode 100644 index ba368db..0000000 --- a/src/backend/binaryen.rs +++ /dev/null @@ -1,1632 +0,0 @@ -//! Binaryen bindings. - -use crate::entity::EntityRef; -use crate::ir; -use crate::{Ieee32, Ieee64}; -use anyhow::{bail, Result}; -use lazy_static::lazy_static; -use libc::{c_char, c_void}; -use std::ffi::{CStr, CString}; - -#[derive(Debug)] -pub struct Module(BinaryenModule); -#[derive(Clone, Copy, Debug)] -pub struct Function(BinaryenModule, BinaryenFunction); -#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] -pub struct Expression(BinaryenModule, BinaryenExpression); -#[derive(Clone, Copy, Debug)] -pub struct Export(BinaryenModule, BinaryenExport); - -pub type BinaryenIndex = u32; -pub type BinaryenType = usize; - -impl Module { - pub fn read(data: &[u8]) -> Result { - let ptr = unsafe { BinaryenModuleRead(data.as_ptr(), data.len()) }; - if ptr.is_null() { - bail!("Failed to parse module"); - } - Ok(Module(ptr)) - } - - pub fn write(&self) -> Result> { - let result = unsafe { BinaryenModuleAllocateAndWrite(self.0, std::ptr::null()) }; - if result.binary.is_null() { - bail!("Failed to serialize module"); - } - let slice = unsafe { - std::slice::from_raw_parts( - result.binary as *const c_void as *const u8, - result.binary_bytes as usize, - ) - }; - Ok(slice.to_vec()) - } - - pub fn new() -> Result { - let ptr = unsafe { BinaryenModuleCreate() }; - if ptr.is_null() { - bail!("Failed to allocate module"); - } - Ok(Module(ptr)) - } - - pub fn add_global(&self, ty: ir::Type, mutable: bool, value: Option) -> ir::Global { - let b_ty = Type::from(ty).to_binaryen(); - let value = value.unwrap_or(0); - let init = match ty { - ir::Type::I32 => Expression::const_i32(self, value as i32), - ir::Type::I64 => Expression::const_i64(self, value as i64), - ir::Type::F32 => Expression::const_f32(self, Ieee32::from_bits(value as u32)), - ir::Type::F64 => Expression::const_f64(self, Ieee64::from_bits(value)), - _ => panic!("Unsupported type"), - }; - - let num = unsafe { BinaryenGetNumGlobals(self.0) }; - let name = CString::new(format!("global{}", num)).unwrap(); - let global = unsafe { BinaryenAddGlobal(self.0, name.as_ptr(), b_ty, mutable, init.1) }; - assert!(!global.is_null()); - ir::Global::from(num) - } - - pub fn add_table(&self, ty: ir::Type, init: usize, max: Option) -> ir::Table { - let ty = Type::from(ty).to_binaryen(); - let num = unsafe { BinaryenGetNumTables(self.0) }; - let max = max.unwrap_or(0); - let name = CString::new(format!("table{}", num)).unwrap(); - let table = unsafe { - BinaryenAddTable( - self.0, - name.as_ptr(), - init as BinaryenIndex, - max as BinaryenIndex, - ty, - ) - }; - assert!(!table.is_null()); - ir::Table::from(num) - } - - pub fn add_table_elem(&self, table: ir::Table, index: usize, elt: ir::Func) { - log::trace!("add_table_elem: func {}", elt); - let table_name = unsafe { - BinaryenTableGetName(BinaryenGetTableByIndex( - self.0, - table.index() as BinaryenIndex, - )) - }; - let func_name = compute_func_name(elt); - let func_name_ptr = func_name.as_ptr(); - let offset = Expression::const_i32(self, index as i32); - let name = CString::new(format!("seg_{}_{}", table.index(), index)).unwrap(); - let seg = unsafe { - BinaryenAddActiveElementSegment( - self.0, - table_name, - name.as_ptr(), - &func_name_ptr as *const *const c_char, - 1, - offset.1, - ) - }; - assert!(!seg.is_null()); - } - - pub fn add_mem( - &self, - init_pages: usize, - max_pages: Option, - segments: &[ir::MemorySegment], - ) -> ir::Memory { - let seg_passive = vec![false; segments.len()]; - let seg_offset = segments - .iter() - .map(|seg| Expression::const_i32(self, seg.offset as i32).1) - .collect::>(); - let seg_data = segments - .iter() - .map(|seg| seg.data.as_ptr() as *const c_char) - .collect::>(); - let seg_size = segments - .iter() - .map(|seg| seg.data.len() as BinaryenIndex) - .collect::>(); - - // Binaryen does not support multi-memory. - unsafe { - BinaryenSetMemory( - self.0, - init_pages as BinaryenIndex, - max_pages.unwrap_or(0) as BinaryenIndex, - std::ptr::null(), - seg_data.as_ptr(), - seg_passive.as_ptr(), - seg_offset.as_ptr(), - seg_size.as_ptr(), - segments.len() as BinaryenIndex, - false, - ); - } - ir::Memory::from(0) - } - - pub fn add_table_import(&self, table: ir::Table, module: &str, name: &str) { - let table_name = unsafe { - BinaryenTableGetName(BinaryenGetTableByIndex( - self.0, - table.index() as BinaryenIndex, - )) - }; - let c_module = std::ffi::CString::new(module).unwrap(); - let c_name = std::ffi::CString::new(name).unwrap(); - unsafe { - BinaryenAddTableImport(self.0, table_name, c_module.as_ptr(), c_name.as_ptr()); - } - } - - pub fn add_func_import( - &self, - func: ir::Func, - module: &str, - name: &str, - params: &[ir::Type], - results: &[ir::Type], - ) { - let num = unsafe { BinaryenGetNumFunctions(self.0) } as usize; - assert_eq!(num, func.index()); - let c_module = std::ffi::CString::new(module).unwrap(); - let c_name = std::ffi::CString::new(name).unwrap(); - let params = tys_to_binaryen(params.iter().copied()); - let results = tys_to_binaryen(results.iter().copied()); - let internal_name = compute_func_name(func); - unsafe { - BinaryenAddFunctionImport( - self.0, - internal_name.as_ptr(), - c_module.as_ptr(), - c_name.as_ptr(), - params, - results, - ); - } - } - - pub fn add_global_import( - &self, - global: ir::Global, - module: &str, - name: &str, - ty: ir::Type, - mutable: bool, - ) { - let global_name = unsafe { - BinaryenGlobalGetName(BinaryenGetGlobalByIndex( - self.0, - global.index() as BinaryenIndex, - )) - }; - let c_module = std::ffi::CString::new(module).unwrap(); - let c_name = std::ffi::CString::new(name).unwrap(); - let ty = Type::from(ty).to_binaryen(); - unsafe { - BinaryenAddGlobalImport( - self.0, - global_name, - c_module.as_ptr(), - c_name.as_ptr(), - ty, - mutable, - ); - } - } - - pub fn add_table_export(&self, table: ir::Table, name: &str) { - let c_name = CString::new(name).unwrap(); - let name = unsafe { - BinaryenTableGetName(BinaryenGetTableByIndex( - self.0, - table.index() as BinaryenIndex, - )) - }; - unsafe { - BinaryenAddTableExport(self.0, name, c_name.as_ptr()); - } - } - - pub fn add_func_export(&self, func: ir::Func, name: &str) { - log::trace!("add_func_export: func {}", func); - let c_name = CString::new(name).unwrap(); - let name = compute_func_name(func); - unsafe { - BinaryenAddFunctionExport(self.0, name.as_ptr(), c_name.as_ptr()); - } - } - - pub fn add_global_export(&self, global: ir::Global, name: &str) { - let c_name = CString::new(name).unwrap(); - let name = unsafe { - BinaryenGlobalGetName(BinaryenGetGlobalByIndex( - self.0, - global.index() as BinaryenIndex, - )) - }; - unsafe { - BinaryenAddGlobalExport(self.0, name, c_name.as_ptr()); - } - } - - pub fn add_memory_export(&self, mem: ir::Memory, name: &str) { - assert_eq!(mem.index(), 0); - let c_name = CString::new(name).unwrap(); - unsafe { - BinaryenAddMemoryExport(self.0, std::ptr::null(), c_name.as_ptr()); - } - } -} - -impl Drop for Module { - fn drop(&mut self) { - unsafe { - BinaryenModuleDispose(self.0); - } - } -} - -fn compute_func_name(func: ir::Func) -> CString { - CString::new(format!("func{}", func.index())).unwrap() -} - -impl Function { - pub fn body(&self) -> Option { - let body = unsafe { BinaryenFunctionGetBody(self.1) }; - if body.is_null() { - None - } else { - Some(Expression(self.0, body)) - } - } - - pub fn set_body(&mut self, body: Expression) { - unsafe { - BinaryenFunctionSetBody(self.0, body.1); - } - } - - pub fn name(&self) -> &str { - let s = unsafe { CStr::from_ptr(BinaryenFunctionGetName(self.1)) }; - s.to_str().unwrap() - } - - pub fn create( - module: &mut Module, - params: impl Iterator, - results: impl Iterator, - locals: impl Iterator, - body: Expression, - ) -> Function { - let params = tys_to_binaryen(params); - let results = tys_to_binaryen(results); - let locals: Vec = locals.map(|ty| Type::from(ty).to_binaryen()).collect(); - let num = unsafe { BinaryenGetNumFunctions(module.0) }; - let name = compute_func_name(ir::Func::new(num as usize)); - log::debug!("creating func {:?}", name); - let ptr = unsafe { - BinaryenAddFunction( - module.0, - name.as_ptr(), - params, - results, - locals.as_ptr(), - locals.len() as BinaryenIndex, - body.1, - ) - }; - Function(module.0, ptr) - } - - pub fn add_local(&mut self, ty: ir::Type) -> usize { - (unsafe { BinaryenFunctionAddVar(self.1, Type::from(ty).to_binaryen()) }) as usize - } -} - -impl Export { - pub fn name(&self) -> &str { - let s = unsafe { CStr::from_ptr(BinaryenExportGetName(self.1)) }; - s.to_str().unwrap() - } - - pub fn value(&self) -> &str { - let s = unsafe { CStr::from_ptr(BinaryenExportGetValue(self.1)) }; - s.to_str().unwrap() - } -} - -struct TypeIds { - none_t: BinaryenType, - i32_t: BinaryenType, - i64_t: BinaryenType, - f32_t: BinaryenType, - f64_t: BinaryenType, - v128_t: BinaryenType, - funcref_t: BinaryenType, -} - -impl TypeIds { - fn get() -> Self { - TypeIds { - none_t: unsafe { BinaryenTypeNone() }, - i32_t: unsafe { BinaryenTypeInt32() }, - i64_t: unsafe { BinaryenTypeInt64() }, - f32_t: unsafe { BinaryenTypeFloat32() }, - f64_t: unsafe { BinaryenTypeFloat64() }, - v128_t: unsafe { BinaryenTypeVec128() }, - funcref_t: unsafe { BinaryenTypeFuncref() }, - } - } -} - -lazy_static! { - static ref TYPE_IDS: TypeIds = TypeIds::get(); -} - -#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] -pub enum Type { - None, - I32, - I64, - F32, - F64, - V128, - FuncRef, -} - -impl Type { - pub(crate) fn to_binaryen(&self) -> BinaryenType { - let tys = &*TYPE_IDS; - match self { - &Type::None => tys.none_t, - &Type::I32 => tys.i32_t, - &Type::I64 => tys.i64_t, - &Type::F32 => tys.f32_t, - &Type::F64 => tys.f64_t, - &Type::V128 => tys.v128_t, - &Type::FuncRef => tys.funcref_t, - } - } -} - -impl From for Type { - fn from(ty: ir::Type) -> Self { - match ty { - ir::Type::I32 => Type::I32, - ir::Type::I64 => Type::I64, - ir::Type::F32 => Type::F32, - ir::Type::F64 => Type::F64, - ir::Type::V128 => Type::V128, - ir::Type::FuncRef => Type::FuncRef, - } - } -} - -pub fn tys_to_binaryen(tys: impl Iterator) -> BinaryenType { - let tys: Vec = tys.map(|ty| Type::from(ty).to_binaryen()).collect(); - unsafe { BinaryenTypeCreate(tys.as_ptr(), tys.len() as BinaryenIndex) } -} - -fn name_to_string(name: *const c_char) -> Option { - if name.is_null() { - None - } else { - Some(unsafe { CStr::from_ptr(name).to_str().unwrap().to_string() }) - } -} - -impl Expression { - pub fn module(&self) -> BinaryenModule { - self.0 - } - - pub fn block(module: &Module, exprs: &[Expression]) -> Expression { - let children = exprs.iter().map(|expr| expr.1).collect::>(); - Expression(module.0, unsafe { - BinaryenBlock( - module.0, - /* name = */ std::ptr::null(), - children.as_ptr(), - children.len() as BinaryenIndex, - BinaryenUndefined(), - ) - }) - } - - pub fn block_append_child(&mut self, child: Expression) { - unsafe { - BinaryenBlockAppendChild(self.1, child.1); - } - } - - pub fn nop(module: &Module) -> Expression { - Expression(module.0, unsafe { BinaryenNop(module.0) }) - } - pub fn unreachable(module: &Module) -> Expression { - Expression(module.0, unsafe { BinaryenUnreachable(module.0) }) - } - pub fn call( - module: &Module, - func: ir::Func, - args: &[Expression], - tys: &[ir::Type], - ) -> Expression { - // Look up the function's name. - let func_name = compute_func_name(func); - // Create the appropriate type for return. - let ret_tuple_ty = tys_to_binaryen(tys.iter().copied()); - let args = args.iter().map(|expr| expr.1).collect::>(); - let expr = unsafe { - BinaryenCall( - module.0, - func_name.as_ptr(), - args.as_ptr(), - args.len() as BinaryenIndex, - ret_tuple_ty, - ) - }; - Expression(module.0, expr) - } - pub fn call_indirect( - module: &Module, - table: ir::Table, - sig: &ir::SignatureData, - target: Expression, - args: &[Expression], - ) -> Expression { - let param_tuple_ty = tys_to_binaryen(sig.params.iter().copied()); - let ret_tuple_ty = tys_to_binaryen(sig.returns.iter().copied()); - let args = args.iter().map(|expr| expr.1).collect::>(); - let table_name = unsafe { - BinaryenTableGetName(BinaryenGetTableByIndex( - module.0, - table.index() as BinaryenIndex, - )) - }; - let expr = unsafe { - BinaryenCallIndirect( - module.0, - table_name, - target.1, - args.as_ptr(), - args.len() as BinaryenIndex, - param_tuple_ty, - ret_tuple_ty, - ) - }; - Expression(module.0, expr) - } - - pub fn local_get(module: &Module, local: ir::Local, ty: ir::Type) -> Expression { - let local = local.index() as BinaryenIndex; - let ty = Type::from(ty).to_binaryen(); - let expr = unsafe { BinaryenLocalGet(module.0, local, ty) }; - Expression(module.0, expr) - } - - pub fn local_set(module: &Module, local: ir::Local, value: Expression) -> Expression { - let local = local.index() as BinaryenIndex; - let expr = unsafe { BinaryenLocalSet(module.0, local, value.1) }; - Expression(module.0, expr) - } - - pub fn local_tee( - module: &Module, - local: ir::Local, - value: Expression, - ty: ir::Type, - ) -> Expression { - let local = local.index() as BinaryenIndex; - let ty = Type::from(ty).to_binaryen(); - let expr = unsafe { BinaryenLocalTee(module.0, local, value.1, ty) }; - Expression(module.0, expr) - } - - pub fn global_get(module: &Module, global: ir::Global, ty: ir::Type) -> Expression { - let global = global.index() as BinaryenIndex; - let ty = Type::from(ty).to_binaryen(); - let expr = unsafe { BinaryenGlobalGet(module.0, global, ty) }; - Expression(module.0, expr) - } - - pub fn global_set(module: &Module, global: ir::Global, value: Expression) -> Expression { - let global = global.index() as BinaryenIndex; - let expr = unsafe { BinaryenGlobalSet(module.0, global, value.1) }; - Expression(module.0, expr) - } - - pub fn select( - module: &Module, - cond: Expression, - if_true: Expression, - if_false: Expression, - ty: ir::Type, - ) -> Expression { - let ty = Type::from(ty).to_binaryen(); - let expr = unsafe { BinaryenSelect(module.0, cond.1, if_true.1, if_false.1, ty) }; - Expression(module.0, expr) - } - - pub fn expr_drop(module: &Module, value: Expression) -> Expression { - Expression(module.0, unsafe { BinaryenDrop(module.0, value.1) }) - } - - pub fn ret(module: &Module, values: &[Expression]) -> Expression { - let expr = if values.len() == 0 { - unsafe { BinaryenReturn(module.0, std::ptr::null()) } - } else if values.len() == 1 { - unsafe { BinaryenReturn(module.0, values[0].1) } - } else { - let exprs = values.iter().map(|e| e.1).collect::>(); - let tuple = unsafe { - BinaryenTupleMake(module.0, exprs.as_ptr(), exprs.len() as BinaryenIndex) - }; - unsafe { BinaryenReturn(module.0, tuple) } - }; - Expression(module.0, expr) - } - - pub fn load( - module: &Module, - bytes: u8, - signed: bool, - offset: u32, - align: u32, - ty: ir::Type, - ptr: Expression, - mem: ir::Memory, - ) -> Expression { - assert_eq!(mem.index(), 0); - let ty = Type::from(ty).to_binaryen(); - let expr = - unsafe { BinaryenLoad(module.0, bytes as u32, signed, offset, align, ty, ptr.1) }; - Expression(module.0, expr) - } - - pub fn store( - module: &Module, - bytes: u8, - offset: u32, - align: u32, - ty: ir::Type, - ptr: Expression, - value: Expression, - mem: ir::Memory, - ) -> Expression { - assert_eq!(mem.index(), 0); - let ty = Type::from(ty).to_binaryen(); - let expr = - unsafe { BinaryenStore(module.0, bytes as u32, offset, align, ptr.1, value.1, ty) }; - Expression(module.0, expr) - } - - pub fn const_i32(module: &Module, value: i32) -> Expression { - let expr = unsafe { BinaryenConst(module.0, BinaryenLiteralInt32(value)) }; - Expression(module.0, expr) - } - pub fn const_i64(module: &Module, value: i64) -> Expression { - let expr = unsafe { BinaryenConst(module.0, BinaryenLiteralInt64(value)) }; - Expression(module.0, expr) - } - pub fn const_f32(module: &Module, value: Ieee32) -> Expression { - let expr = - unsafe { BinaryenConst(module.0, BinaryenLiteralFloat32Bits(value.bits() as i32)) }; - Expression(module.0, expr) - } - pub fn const_f64(module: &Module, value: Ieee64) -> Expression { - let expr = - unsafe { BinaryenConst(module.0, BinaryenLiteralFloat64Bits(value.bits() as i64)) }; - Expression(module.0, expr) - } - - pub fn table_get( - module: &Module, - table: ir::Table, - index: Expression, - ty: ir::Type, - ) -> Expression { - let table_name = unsafe { - BinaryenTableGetName(BinaryenGetTableByIndex(module.0, table.index() as u32)) - }; - let ty = Type::from(ty).to_binaryen(); - let expr = unsafe { BinaryenTableGet(module.0, table_name, index.1, ty) }; - Expression(module.0, expr) - } - - pub fn table_set( - module: &Module, - table: ir::Table, - index: Expression, - value: Expression, - ) -> Expression { - let table_name = unsafe { - BinaryenTableGetName(BinaryenGetTableByIndex(module.0, table.index() as u32)) - }; - let expr = unsafe { BinaryenTableSet(module.0, table_name, index.1, value.1) }; - Expression(module.0, expr) - } - - pub fn table_grow( - module: &Module, - table: ir::Table, - delta: Expression, - value: Expression, - ) -> Expression { - let table_name = unsafe { - BinaryenTableGetName(BinaryenGetTableByIndex(module.0, table.index() as u32)) - }; - let expr = unsafe { BinaryenTableGrow(module.0, table_name, value.1, delta.1) }; - Expression(module.0, expr) - } - - pub fn table_size(module: &Module, table: ir::Table) -> Expression { - let table_name = unsafe { - BinaryenTableGetName(BinaryenGetTableByIndex(module.0, table.index() as u32)) - }; - let expr = unsafe { BinaryenTableSize(module.0, table_name) }; - Expression(module.0, expr) - } - - pub fn memory_size(module: &Module, mem: ir::Memory) -> Expression { - assert_eq!(mem.index(), 0); - Expression(module.0, unsafe { BinaryenMemorySize(module.0) }) - } - - pub fn memory_grow(module: &Module, mem: ir::Memory, delta: Expression) -> Expression { - assert_eq!(mem.index(), 0); - Expression(module.0, unsafe { BinaryenMemoryGrow(module.0, delta.1) }) - } -} - -macro_rules! operator { - (unary $name:tt, $bin_name:tt) => { - impl Expression { - pub fn $name(module: &Module, arg: Expression) -> Expression { - Expression(module.0, unsafe { - BinaryenUnary(module.0, $bin_name(), arg.1) - }) - } - } - }; - (binary $name:tt, $bin_name:tt) => { - impl Expression { - pub fn $name(module: &Module, arg0: Expression, arg1: Expression) -> Expression { - Expression(module.0, unsafe { - BinaryenBinary(module.0, $bin_name(), arg0.1, arg1.1) - }) - } - } - }; -} - -operator!(unary i32_eqz, BinaryenEqZInt32); -operator!(binary i32_eq, BinaryenEqInt32); -operator!(binary i32_ne, BinaryenNeInt32); -operator!(binary i32_lt_s, BinaryenLtSInt32); -operator!(binary i32_lt_u, BinaryenLtUInt32); -operator!(binary i32_gt_s, BinaryenGtSInt32); -operator!(binary i32_gt_u, BinaryenGtUInt32); -operator!(binary i32_le_s, BinaryenLeSInt32); -operator!(binary i32_le_u, BinaryenLeUInt32); -operator!(binary i32_ge_s, BinaryenGeSInt32); -operator!(binary i32_ge_u, BinaryenGeUInt32); - -operator!(unary i64_eqz, BinaryenEqZInt64); -operator!(binary i64_eq, BinaryenEqInt64); -operator!(binary i64_ne, BinaryenNeInt64); -operator!(binary i64_lt_s, BinaryenLtSInt64); -operator!(binary i64_lt_u, BinaryenLtUInt64); -operator!(binary i64_gt_s, BinaryenGtSInt64); -operator!(binary i64_gt_u, BinaryenGtUInt64); -operator!(binary i64_le_s, BinaryenLeSInt64); -operator!(binary i64_le_u, BinaryenLeUInt64); -operator!(binary i64_ge_s, BinaryenGeSInt64); -operator!(binary i64_ge_u, BinaryenGeUInt64); - -operator!(binary f32_eq, BinaryenEqFloat32); -operator!(binary f32_ne, BinaryenNeFloat32); -operator!(binary f32_lt, BinaryenLtFloat32); -operator!(binary f32_gt, BinaryenGtFloat32); -operator!(binary f32_le, BinaryenLeFloat32); -operator!(binary f32_ge, BinaryenGeFloat32); - -operator!(binary f64_eq, BinaryenEqFloat64); -operator!(binary f64_ne, BinaryenNeFloat64); -operator!(binary f64_lt, BinaryenLtFloat64); -operator!(binary f64_gt, BinaryenGtFloat64); -operator!(binary f64_le, BinaryenLeFloat64); -operator!(binary f64_ge, BinaryenGeFloat64); - -operator!(unary i32_clz, BinaryenClzInt32); -operator!(unary i32_ctz, BinaryenCtzInt32); -operator!(unary i32_popcnt, BinaryenPopcntInt32); - -operator!(binary i32_add, BinaryenAddInt32); -operator!(binary i32_sub, BinaryenSubInt32); -operator!(binary i32_mul, BinaryenMulInt32); -operator!(binary i32_div_s, BinaryenDivSInt32); -operator!(binary i32_div_u, BinaryenDivUInt32); -operator!(binary i32_rem_s, BinaryenRemSInt32); -operator!(binary i32_rem_u, BinaryenRemUInt32); -operator!(binary i32_and, BinaryenAndInt32); -operator!(binary i32_or, BinaryenOrInt32); -operator!(binary i32_xor, BinaryenXorInt32); -operator!(binary i32_shl, BinaryenShlInt32); -operator!(binary i32_shr_s, BinaryenShrSInt32); -operator!(binary i32_shr_u, BinaryenShrUInt32); -operator!(binary i32_rotl, BinaryenRotLInt32); -operator!(binary i32_rotr, BinaryenRotRInt32); - -operator!(unary i64_clz, BinaryenClzInt64); -operator!(unary i64_ctz, BinaryenCtzInt64); -operator!(unary i64_popcnt, BinaryenPopcntInt64); - -operator!(binary i64_add, BinaryenAddInt64); -operator!(binary i64_sub, BinaryenSubInt64); -operator!(binary i64_mul, BinaryenMulInt64); -operator!(binary i64_div_s, BinaryenDivSInt64); -operator!(binary i64_div_u, BinaryenDivUInt64); -operator!(binary i64_rem_s, BinaryenRemSInt64); -operator!(binary i64_rem_u, BinaryenRemUInt64); -operator!(binary i64_and, BinaryenAndInt64); -operator!(binary i64_or, BinaryenOrInt64); -operator!(binary i64_xor, BinaryenXorInt64); -operator!(binary i64_shl, BinaryenShlInt64); -operator!(binary i64_shr_s, BinaryenShrSInt64); -operator!(binary i64_shr_u, BinaryenShrUInt64); -operator!(binary i64_rotl, BinaryenRotLInt64); -operator!(binary i64_rotr, BinaryenRotRInt64); - -operator!(unary f32_abs, BinaryenAbsFloat32); -operator!(unary f32_neg, BinaryenNegFloat32); -operator!(unary f32_ceil, BinaryenCeilFloat32); -operator!(unary f32_floor, BinaryenFloorFloat32); -operator!(unary f32_trunc, BinaryenTruncFloat32); -operator!(unary f32_nearest, BinaryenNearestFloat32); -operator!(unary f32_sqrt, BinaryenSqrtFloat32); - -operator!(binary f32_add, BinaryenAddFloat32); -operator!(binary f32_sub, BinaryenSubFloat32); -operator!(binary f32_mul, BinaryenMulFloat32); -operator!(binary f32_div, BinaryenDivFloat32); -operator!(binary f32_min, BinaryenMinFloat32); -operator!(binary f32_max, BinaryenMaxFloat32); -operator!(binary f32_copysign, BinaryenCopySignFloat32); - -operator!(unary f64_abs, BinaryenAbsFloat64); -operator!(unary f64_neg, BinaryenNegFloat64); -operator!(unary f64_ceil, BinaryenCeilFloat64); -operator!(unary f64_floor, BinaryenFloorFloat64); -operator!(unary f64_trunc, BinaryenTruncFloat64); -operator!(unary f64_nearest, BinaryenNearestFloat64); -operator!(unary f64_sqrt, BinaryenSqrtFloat64); - -operator!(binary f64_add, BinaryenAddFloat64); -operator!(binary f64_sub, BinaryenSubFloat64); -operator!(binary f64_mul, BinaryenMulFloat64); -operator!(binary f64_div, BinaryenDivFloat64); -operator!(binary f64_min, BinaryenMinFloat64); -operator!(binary f64_max, BinaryenMaxFloat64); -operator!(binary f64_copysign, BinaryenCopySignFloat64); - -operator!(unary i32_wrap_i64, BinaryenWrapInt64); -operator!(unary i32_trunc_f32_s, BinaryenTruncSFloat32ToInt32); -operator!(unary i32_trunc_f32_u, BinaryenTruncUFloat32ToInt32); -operator!(unary i32_trunc_f64_s, BinaryenTruncSFloat64ToInt32); -operator!(unary i32_trunc_f64_u, BinaryenTruncUFloat64ToInt32); -operator!(unary i64_extend_i32_s, BinaryenExtendSInt32); -operator!(unary i64_extend_i32_u, BinaryenExtendUInt32); -operator!(unary i64_trunc_f32_s, BinaryenTruncSFloat32ToInt64); -operator!(unary i64_trunc_f32_u, BinaryenTruncUFloat32ToInt64); -operator!(unary i64_trunc_f64_s, BinaryenTruncSFloat64ToInt64); -operator!(unary i64_trunc_f64_u, BinaryenTruncUFloat64ToInt64); -operator!(unary f32_convert_i32_s, BinaryenConvertSInt32ToFloat32); -operator!(unary f32_convert_i32_u, BinaryenConvertUInt32ToFloat32); -operator!(unary f32_convert_i64_s, BinaryenConvertSInt64ToFloat32); -operator!(unary f32_convert_i64_u, BinaryenConvertUInt64ToFloat32); -operator!(unary f32_demote_f64, BinaryenDemoteFloat64); -operator!(unary f64_convert_i32_s, BinaryenConvertSInt32ToFloat64); -operator!(unary f64_convert_i32_u, BinaryenConvertUInt32ToFloat64); -operator!(unary f64_convert_i64_s, BinaryenConvertSInt64ToFloat64); -operator!(unary f64_convert_i64_u, BinaryenConvertUInt64ToFloat64); -operator!(unary f64_promote_f32, BinaryenPromoteFloat32); -operator!(unary i32_extend_8_s, BinaryenExtendS8Int32); -operator!(unary i32_extend_16_s, BinaryenExtendS16Int32); -operator!(unary i64_extend_8_s, BinaryenExtendS8Int64); -operator!(unary i64_extend_16_s, BinaryenExtendS16Int64); -operator!(unary i64_extend_32_s, BinaryenExtendS32Int64); -operator!(unary i32_trunc_sat_f32_s, BinaryenTruncSatSFloat32ToInt32); -operator!(unary i32_trunc_sat_f32_u, BinaryenTruncSatUFloat32ToInt32); -operator!(unary i32_trunc_sat_f64_s, BinaryenTruncSatSFloat64ToInt32); -operator!(unary i32_trunc_sat_f64_u, BinaryenTruncSatUFloat64ToInt32); -operator!(unary i64_trunc_sat_f32_s, BinaryenTruncSatSFloat32ToInt64); -operator!(unary i64_trunc_sat_f32_u, BinaryenTruncSatUFloat32ToInt64); -operator!(unary i64_trunc_sat_f64_s, BinaryenTruncSatSFloat64ToInt64); -operator!(unary i64_trunc_sat_f64_u, BinaryenTruncSatUFloat64ToInt64); -operator!(unary f32_reinterpret_i32, BinaryenReinterpretInt32); -operator!(unary f64_reinterpret_i64, BinaryenReinterpretInt64); -operator!(unary i32_reinterpret_f32, BinaryenReinterpretFloat32); -operator!(unary i64_reinterpret_f64, BinaryenReinterpretFloat64); - -pub type BinaryenModule = *const c_void; -type BinaryenFunction = *const c_void; -type BinaryenExpression = *const c_void; -type BinaryenExport = *const c_void; -type BinaryenRelooper = *const c_void; -type BinaryenRelooperBlock = *const c_void; -type BinaryenTable = *const c_void; -type BinaryenGlobal = *const c_void; -type BinaryenElementSegment = *const c_void; - -#[repr(C)] -struct BinaryenModuleAllocateAndWriteResult { - binary: *mut c_void, - binary_bytes: libc::size_t, - source_map: *mut c_char, -} - -impl Drop for BinaryenModuleAllocateAndWriteResult { - fn drop(&mut self) { - unsafe { - libc::free(self.binary); - libc::free(self.source_map as *mut c_void); - } - } -} - -pub struct Relooper(BinaryenModule, BinaryenRelooper); - -#[derive(Clone, Copy, PartialEq, Eq)] -pub struct RelooperBlock(BinaryenRelooperBlock); - -impl Relooper { - pub fn new(module: &Module) -> Relooper { - let ptr = unsafe { RelooperCreate(module.0) }; - Relooper(module.0, ptr) - } - - pub fn construct(self, entry: RelooperBlock, index_var: usize) -> Expression { - let module = self.0; - let expr = unsafe { RelooperRenderAndDispose(self.1, entry.0, index_var as BinaryenIndex) }; - std::mem::forget(self); - Expression(module, expr) - } - - pub fn add_block(&mut self, expr: Expression) -> RelooperBlock { - RelooperBlock(unsafe { RelooperAddBlock(self.1, expr.1) }) - } - - pub fn add_block_with_switch(&mut self, expr: Expression, sel: Expression) -> RelooperBlock { - RelooperBlock(unsafe { RelooperAddBlockWithSwitch(self.1, expr.1, sel.1) }) - } -} - -impl RelooperBlock { - pub fn cond_branch(&self, to: RelooperBlock, cond: Expression, edge: Expression) { - unsafe { - RelooperAddBranch(self.0, to.0, cond.1, edge.1); - } - } - - pub fn branch(&self, to: RelooperBlock, edge: Expression) { - unsafe { - RelooperAddBranch(self.0, to.0, std::ptr::null(), edge.1); - } - } - - pub fn switch(&self, to: RelooperBlock, edge: Expression, indices: &[BinaryenIndex]) { - unsafe { - RelooperAddBranchForSwitch( - self.0, - to.0, - indices.as_ptr(), - indices.len() as BinaryenIndex, - edge.1, - ); - } - } -} - -impl Drop for Relooper { - fn drop(&mut self) { - panic!("Relooper dropped without constructing/disposing"); - } -} - -#[link(name = "binaryen")] -extern "C" { - fn BinaryenModuleRead(data: *const u8, len: usize) -> BinaryenModule; - fn BinaryenModuleCreate() -> BinaryenModule; - fn BinaryenModuleDispose(ptr: BinaryenModule); - fn BinaryenModuleAllocateAndWrite( - ptr: BinaryenModule, - sourceMapUrl: *const c_char, - ) -> BinaryenModuleAllocateAndWriteResult; - fn BinaryenGetNumFunctions(ptr: BinaryenModule) -> u32; - fn BinaryenGetFunction(ptr: BinaryenModule, name: *const c_char) -> BinaryenFunction; - fn BinaryenFunctionGetBody(ptr: BinaryenFunction) -> BinaryenExpression; - fn BinaryenFunctionSetBody(ptr: BinaryenFunction, body: BinaryenExpression); - fn BinaryenFunctionGetName(ptr: BinaryenFunction) -> *const c_char; - fn BinaryenFunctionAddVar(ptr: BinaryenFunction, ty: BinaryenType) -> BinaryenIndex; - fn BinaryenGetExport(ptr: BinaryenModule, name: *const c_char) -> BinaryenExport; - fn BinaryenGetNumExports(ptr: BinaryenModule) -> u32; - fn BinaryenGetExportByIndex(ptr: BinaryenModule, index: u32) -> BinaryenExport; - fn BinaryenExportGetName(ptr: BinaryenFunction) -> *const c_char; - fn BinaryenExportGetValue(ptr: BinaryenFunction) -> *const c_char; - fn BinaryenExportGetKind(ptr: BinaryenFunction) -> u32; - fn BinaryenExternalFunction() -> u32; - fn BinaryenGetTableByIndex(ptr: BinaryenModule, index: BinaryenIndex) -> BinaryenTable; - - fn BinaryenTableGetName(table: BinaryenTable) -> *const c_char; - - fn BinaryenBlockGetNumChildren(ptr: BinaryenExpression) -> u32; - fn BinaryenBlockAppendChild( - ptr: BinaryenExpression, - child: BinaryenExpression, - ) -> BinaryenIndex; - - fn BinaryenGetNumMemorySegments(module: BinaryenModule) -> u32; - fn BinaryenGetMemorySegmentByteOffset(module: BinaryenModule, index: u32) -> u32; - fn BinaryenGetMemorySegmentByteLength(module: BinaryenModule, index: u32) -> usize; - fn BinaryenCopyMemorySegmentData(module: BinaryenModule, index: u32, buffer: *mut u8); - - fn BinaryenTypeNone() -> BinaryenType; - fn BinaryenTypeInt32() -> BinaryenType; - fn BinaryenTypeInt64() -> BinaryenType; - fn BinaryenTypeFloat32() -> BinaryenType; - fn BinaryenTypeFloat64() -> BinaryenType; - fn BinaryenTypeVec128() -> BinaryenType; - fn BinaryenTypeFuncref() -> BinaryenType; - - fn BinaryenTypeCreate(tys: *const BinaryenType, n_tys: BinaryenIndex) -> BinaryenType; - - fn BinaryenConst(module: BinaryenModule, lit: BinaryenLiteral) -> BinaryenExpression; - fn BinaryenUnreachable(module: BinaryenModule) -> BinaryenExpression; - fn BinaryenNop(module: BinaryenModule) -> BinaryenExpression; - fn BinaryenLocalGet( - module: BinaryenModule, - local: BinaryenIndex, - ty: BinaryenType, - ) -> BinaryenExpression; - fn BinaryenLocalSet( - module: BinaryenModule, - local: BinaryenIndex, - value: BinaryenExpression, - ) -> BinaryenExpression; - fn BinaryenLocalTee( - module: BinaryenModule, - local: BinaryenIndex, - value: BinaryenExpression, - ty: BinaryenType, - ) -> BinaryenExpression; - fn BinaryenGlobalGet( - module: BinaryenModule, - local: BinaryenIndex, - ty: BinaryenType, - ) -> BinaryenExpression; - fn BinaryenGlobalSet( - module: BinaryenModule, - local: BinaryenIndex, - value: BinaryenExpression, - ) -> BinaryenExpression; - fn BinaryenSelect( - module: BinaryenModule, - cond: BinaryenExpression, - if_true: BinaryenExpression, - if_false: BinaryenExpression, - ty: BinaryenType, - ) -> BinaryenExpression; - fn BinaryenBlock( - module: BinaryenModule, - name: *const c_char, - children: *const BinaryenExpression, - n_children: BinaryenIndex, - ty: BinaryenType, - ) -> BinaryenExpression; - fn BinaryenTupleMake( - module: BinaryenModule, - operands: *const BinaryenExpression, - n_operands: BinaryenIndex, - ) -> BinaryenExpression; - fn BinaryenReturn(module: BinaryenModule, expr: BinaryenExpression) -> BinaryenExpression; - fn BinaryenDrop(module: BinaryenModule, expr: BinaryenExpression) -> BinaryenExpression; - fn BinaryenUnary( - module: BinaryenModule, - op: BinaryenOp, - arg: BinaryenExpression, - ) -> BinaryenExpression; - fn BinaryenBinary( - module: BinaryenModule, - op: BinaryenOp, - left: BinaryenExpression, - right: BinaryenExpression, - ) -> BinaryenExpression; - fn BinaryenCall( - module: BinaryenModule, - target: *const c_char, - operands: *const BinaryenExpression, - n_operands: BinaryenIndex, - ret_type: BinaryenType, - ) -> BinaryenExpression; - fn BinaryenCallIndirect( - module: BinaryenModule, - table: *const c_char, - target: BinaryenExpression, - operands: *const BinaryenExpression, - n_operands: BinaryenIndex, - param_type: BinaryenType, - ret_type: BinaryenType, - ) -> BinaryenExpression; - fn BinaryenLoad( - module: BinaryenModule, - bytes: u32, - signed: bool, - offset: u32, - align: u32, - ty: BinaryenType, - ptr: BinaryenExpression, - ) -> BinaryenExpression; - fn BinaryenStore( - module: BinaryenModule, - bytes: u32, - offset: u32, - align: u32, - ptr: BinaryenExpression, - value: BinaryenExpression, - ty: BinaryenType, - ) -> BinaryenExpression; - fn BinaryenMemorySize(module: BinaryenModule) -> BinaryenExpression; - fn BinaryenMemoryGrow(module: BinaryenModule, expr: BinaryenExpression) -> BinaryenExpression; - fn BinaryenTableGet( - module: BinaryenModule, - name: *const c_char, - index: BinaryenExpression, - ty: BinaryenType, - ) -> BinaryenExpression; - fn BinaryenTableSet( - module: BinaryenModule, - name: *const c_char, - index: BinaryenExpression, - value: BinaryenExpression, - ) -> BinaryenExpression; - fn BinaryenTableGrow( - module: BinaryenModule, - name: *const c_char, - value: BinaryenExpression, - delta: BinaryenExpression, - ) -> BinaryenExpression; - fn BinaryenTableSize(module: BinaryenModule, name: *const c_char) -> BinaryenExpression; - - fn BinaryenAddFunction( - module: BinaryenModule, - name: *const c_char, - params: BinaryenType, - results: BinaryenType, - vars: *const BinaryenType, - n_vars: BinaryenIndex, - body: BinaryenExpression, - ) -> BinaryenFunction; - - fn BinaryenUndefined() -> BinaryenType; - - fn BinaryenLiteralInt32(x: i32) -> BinaryenLiteral; - fn BinaryenLiteralInt64(x: i64) -> BinaryenLiteral; - fn BinaryenLiteralFloat32Bits(x: i32) -> BinaryenLiteral; - fn BinaryenLiteralFloat64Bits(x: i64) -> BinaryenLiteral; - - fn RelooperCreate(module: BinaryenModule) -> BinaryenRelooper; - fn RelooperRenderAndDispose( - r: BinaryenRelooper, - entry: BinaryenRelooperBlock, - labelVar: BinaryenIndex, - ) -> BinaryenExpression; - fn RelooperAddBlock(r: BinaryenRelooper, code: BinaryenExpression) -> BinaryenRelooperBlock; - fn RelooperAddBranch( - from: BinaryenRelooperBlock, - to: BinaryenRelooperBlock, - cond: BinaryenExpression, - edge_code: BinaryenExpression, - ); - fn RelooperAddBlockWithSwitch( - r: BinaryenRelooper, - code: BinaryenExpression, - selector: BinaryenExpression, - ) -> BinaryenRelooperBlock; - fn RelooperAddBranchForSwitch( - from: BinaryenRelooperBlock, - to: BinaryenRelooperBlock, - indices: *const BinaryenIndex, - n_indices: BinaryenIndex, - edge_code: BinaryenExpression, - ); - - fn BinaryenClzInt32() -> BinaryenOp; - fn BinaryenCtzInt32() -> BinaryenOp; - fn BinaryenPopcntInt32() -> BinaryenOp; - fn BinaryenNegFloat32() -> BinaryenOp; - fn BinaryenAbsFloat32() -> BinaryenOp; - fn BinaryenCeilFloat32() -> BinaryenOp; - fn BinaryenFloorFloat32() -> BinaryenOp; - fn BinaryenTruncFloat32() -> BinaryenOp; - fn BinaryenNearestFloat32() -> BinaryenOp; - fn BinaryenSqrtFloat32() -> BinaryenOp; - fn BinaryenEqZInt32() -> BinaryenOp; - fn BinaryenClzInt64() -> BinaryenOp; - fn BinaryenCtzInt64() -> BinaryenOp; - fn BinaryenPopcntInt64() -> BinaryenOp; - fn BinaryenNegFloat64() -> BinaryenOp; - fn BinaryenAbsFloat64() -> BinaryenOp; - fn BinaryenCeilFloat64() -> BinaryenOp; - fn BinaryenFloorFloat64() -> BinaryenOp; - fn BinaryenTruncFloat64() -> BinaryenOp; - fn BinaryenNearestFloat64() -> BinaryenOp; - fn BinaryenSqrtFloat64() -> BinaryenOp; - fn BinaryenEqZInt64() -> BinaryenOp; - fn BinaryenExtendSInt32() -> BinaryenOp; - fn BinaryenExtendUInt32() -> BinaryenOp; - fn BinaryenWrapInt64() -> BinaryenOp; - fn BinaryenTruncSFloat32ToInt32() -> BinaryenOp; - fn BinaryenTruncSFloat32ToInt64() -> BinaryenOp; - fn BinaryenTruncUFloat32ToInt32() -> BinaryenOp; - fn BinaryenTruncUFloat32ToInt64() -> BinaryenOp; - fn BinaryenTruncSFloat64ToInt32() -> BinaryenOp; - fn BinaryenTruncSFloat64ToInt64() -> BinaryenOp; - fn BinaryenTruncUFloat64ToInt32() -> BinaryenOp; - fn BinaryenTruncUFloat64ToInt64() -> BinaryenOp; - fn BinaryenReinterpretFloat32() -> BinaryenOp; - fn BinaryenReinterpretFloat64() -> BinaryenOp; - fn BinaryenConvertSInt32ToFloat32() -> BinaryenOp; - fn BinaryenConvertSInt32ToFloat64() -> BinaryenOp; - fn BinaryenConvertUInt32ToFloat32() -> BinaryenOp; - fn BinaryenConvertUInt32ToFloat64() -> BinaryenOp; - fn BinaryenConvertSInt64ToFloat32() -> BinaryenOp; - fn BinaryenConvertSInt64ToFloat64() -> BinaryenOp; - fn BinaryenConvertUInt64ToFloat32() -> BinaryenOp; - fn BinaryenConvertUInt64ToFloat64() -> BinaryenOp; - fn BinaryenPromoteFloat32() -> BinaryenOp; - fn BinaryenDemoteFloat64() -> BinaryenOp; - fn BinaryenReinterpretInt32() -> BinaryenOp; - fn BinaryenReinterpretInt64() -> BinaryenOp; - fn BinaryenExtendS8Int32() -> BinaryenOp; - fn BinaryenExtendS16Int32() -> BinaryenOp; - fn BinaryenExtendS8Int64() -> BinaryenOp; - fn BinaryenExtendS16Int64() -> BinaryenOp; - fn BinaryenExtendS32Int64() -> BinaryenOp; - fn BinaryenAddInt32() -> BinaryenOp; - fn BinaryenSubInt32() -> BinaryenOp; - fn BinaryenMulInt32() -> BinaryenOp; - fn BinaryenDivSInt32() -> BinaryenOp; - fn BinaryenDivUInt32() -> BinaryenOp; - fn BinaryenRemSInt32() -> BinaryenOp; - fn BinaryenRemUInt32() -> BinaryenOp; - fn BinaryenAndInt32() -> BinaryenOp; - fn BinaryenOrInt32() -> BinaryenOp; - fn BinaryenXorInt32() -> BinaryenOp; - fn BinaryenShlInt32() -> BinaryenOp; - fn BinaryenShrUInt32() -> BinaryenOp; - fn BinaryenShrSInt32() -> BinaryenOp; - fn BinaryenRotLInt32() -> BinaryenOp; - fn BinaryenRotRInt32() -> BinaryenOp; - fn BinaryenEqInt32() -> BinaryenOp; - fn BinaryenNeInt32() -> BinaryenOp; - fn BinaryenLtSInt32() -> BinaryenOp; - fn BinaryenLtUInt32() -> BinaryenOp; - fn BinaryenLeSInt32() -> BinaryenOp; - fn BinaryenLeUInt32() -> BinaryenOp; - fn BinaryenGtSInt32() -> BinaryenOp; - fn BinaryenGtUInt32() -> BinaryenOp; - fn BinaryenGeSInt32() -> BinaryenOp; - fn BinaryenGeUInt32() -> BinaryenOp; - fn BinaryenAddInt64() -> BinaryenOp; - fn BinaryenSubInt64() -> BinaryenOp; - fn BinaryenMulInt64() -> BinaryenOp; - fn BinaryenDivSInt64() -> BinaryenOp; - fn BinaryenDivUInt64() -> BinaryenOp; - fn BinaryenRemSInt64() -> BinaryenOp; - fn BinaryenRemUInt64() -> BinaryenOp; - fn BinaryenAndInt64() -> BinaryenOp; - fn BinaryenOrInt64() -> BinaryenOp; - fn BinaryenXorInt64() -> BinaryenOp; - fn BinaryenShlInt64() -> BinaryenOp; - fn BinaryenShrUInt64() -> BinaryenOp; - fn BinaryenShrSInt64() -> BinaryenOp; - fn BinaryenRotLInt64() -> BinaryenOp; - fn BinaryenRotRInt64() -> BinaryenOp; - fn BinaryenEqInt64() -> BinaryenOp; - fn BinaryenNeInt64() -> BinaryenOp; - fn BinaryenLtSInt64() -> BinaryenOp; - fn BinaryenLtUInt64() -> BinaryenOp; - fn BinaryenLeSInt64() -> BinaryenOp; - fn BinaryenLeUInt64() -> BinaryenOp; - fn BinaryenGtSInt64() -> BinaryenOp; - fn BinaryenGtUInt64() -> BinaryenOp; - fn BinaryenGeSInt64() -> BinaryenOp; - fn BinaryenGeUInt64() -> BinaryenOp; - fn BinaryenAddFloat32() -> BinaryenOp; - fn BinaryenSubFloat32() -> BinaryenOp; - fn BinaryenMulFloat32() -> BinaryenOp; - fn BinaryenDivFloat32() -> BinaryenOp; - fn BinaryenCopySignFloat32() -> BinaryenOp; - fn BinaryenMinFloat32() -> BinaryenOp; - fn BinaryenMaxFloat32() -> BinaryenOp; - fn BinaryenEqFloat32() -> BinaryenOp; - fn BinaryenNeFloat32() -> BinaryenOp; - fn BinaryenLtFloat32() -> BinaryenOp; - fn BinaryenLeFloat32() -> BinaryenOp; - fn BinaryenGtFloat32() -> BinaryenOp; - fn BinaryenGeFloat32() -> BinaryenOp; - fn BinaryenAddFloat64() -> BinaryenOp; - fn BinaryenSubFloat64() -> BinaryenOp; - fn BinaryenMulFloat64() -> BinaryenOp; - fn BinaryenDivFloat64() -> BinaryenOp; - fn BinaryenCopySignFloat64() -> BinaryenOp; - fn BinaryenMinFloat64() -> BinaryenOp; - fn BinaryenMaxFloat64() -> BinaryenOp; - fn BinaryenEqFloat64() -> BinaryenOp; - fn BinaryenNeFloat64() -> BinaryenOp; - fn BinaryenLtFloat64() -> BinaryenOp; - fn BinaryenLeFloat64() -> BinaryenOp; - fn BinaryenGtFloat64() -> BinaryenOp; - fn BinaryenGeFloat64() -> BinaryenOp; - fn BinaryenAtomicRMWAdd() -> BinaryenOp; - fn BinaryenAtomicRMWSub() -> BinaryenOp; - fn BinaryenAtomicRMWAnd() -> BinaryenOp; - fn BinaryenAtomicRMWOr() -> BinaryenOp; - fn BinaryenAtomicRMWXor() -> BinaryenOp; - fn BinaryenAtomicRMWXchg() -> BinaryenOp; - fn BinaryenTruncSatSFloat32ToInt32() -> BinaryenOp; - fn BinaryenTruncSatSFloat32ToInt64() -> BinaryenOp; - fn BinaryenTruncSatUFloat32ToInt32() -> BinaryenOp; - fn BinaryenTruncSatUFloat32ToInt64() -> BinaryenOp; - fn BinaryenTruncSatSFloat64ToInt32() -> BinaryenOp; - fn BinaryenTruncSatSFloat64ToInt64() -> BinaryenOp; - fn BinaryenTruncSatUFloat64ToInt32() -> BinaryenOp; - fn BinaryenTruncSatUFloat64ToInt64() -> BinaryenOp; - fn BinaryenSplatVecI8x16() -> BinaryenOp; - fn BinaryenExtractLaneSVecI8x16() -> BinaryenOp; - fn BinaryenExtractLaneUVecI8x16() -> BinaryenOp; - fn BinaryenReplaceLaneVecI8x16() -> BinaryenOp; - fn BinaryenSplatVecI16x8() -> BinaryenOp; - fn BinaryenExtractLaneSVecI16x8() -> BinaryenOp; - fn BinaryenExtractLaneUVecI16x8() -> BinaryenOp; - fn BinaryenReplaceLaneVecI16x8() -> BinaryenOp; - fn BinaryenSplatVecI32x4() -> BinaryenOp; - fn BinaryenExtractLaneVecI32x4() -> BinaryenOp; - fn BinaryenReplaceLaneVecI32x4() -> BinaryenOp; - fn BinaryenSplatVecI64x2() -> BinaryenOp; - fn BinaryenExtractLaneVecI64x2() -> BinaryenOp; - fn BinaryenReplaceLaneVecI64x2() -> BinaryenOp; - fn BinaryenSplatVecF32x4() -> BinaryenOp; - fn BinaryenExtractLaneVecF32x4() -> BinaryenOp; - fn BinaryenReplaceLaneVecF32x4() -> BinaryenOp; - fn BinaryenSplatVecF64x2() -> BinaryenOp; - fn BinaryenExtractLaneVecF64x2() -> BinaryenOp; - fn BinaryenReplaceLaneVecF64x2() -> BinaryenOp; - fn BinaryenEqVecI8x16() -> BinaryenOp; - fn BinaryenNeVecI8x16() -> BinaryenOp; - fn BinaryenLtSVecI8x16() -> BinaryenOp; - fn BinaryenLtUVecI8x16() -> BinaryenOp; - fn BinaryenGtSVecI8x16() -> BinaryenOp; - fn BinaryenGtUVecI8x16() -> BinaryenOp; - fn BinaryenLeSVecI8x16() -> BinaryenOp; - fn BinaryenLeUVecI8x16() -> BinaryenOp; - fn BinaryenGeSVecI8x16() -> BinaryenOp; - fn BinaryenGeUVecI8x16() -> BinaryenOp; - fn BinaryenEqVecI16x8() -> BinaryenOp; - fn BinaryenNeVecI16x8() -> BinaryenOp; - fn BinaryenLtSVecI16x8() -> BinaryenOp; - fn BinaryenLtUVecI16x8() -> BinaryenOp; - fn BinaryenGtSVecI16x8() -> BinaryenOp; - fn BinaryenGtUVecI16x8() -> BinaryenOp; - fn BinaryenLeSVecI16x8() -> BinaryenOp; - fn BinaryenLeUVecI16x8() -> BinaryenOp; - fn BinaryenGeSVecI16x8() -> BinaryenOp; - fn BinaryenGeUVecI16x8() -> BinaryenOp; - fn BinaryenEqVecI32x4() -> BinaryenOp; - fn BinaryenNeVecI32x4() -> BinaryenOp; - fn BinaryenLtSVecI32x4() -> BinaryenOp; - fn BinaryenLtUVecI32x4() -> BinaryenOp; - fn BinaryenGtSVecI32x4() -> BinaryenOp; - fn BinaryenGtUVecI32x4() -> BinaryenOp; - fn BinaryenLeSVecI32x4() -> BinaryenOp; - fn BinaryenLeUVecI32x4() -> BinaryenOp; - fn BinaryenGeSVecI32x4() -> BinaryenOp; - fn BinaryenGeUVecI32x4() -> BinaryenOp; - fn BinaryenEqVecI64x2() -> BinaryenOp; - fn BinaryenNeVecI64x2() -> BinaryenOp; - fn BinaryenLtSVecI64x2() -> BinaryenOp; - fn BinaryenGtSVecI64x2() -> BinaryenOp; - fn BinaryenLeSVecI64x2() -> BinaryenOp; - fn BinaryenGeSVecI64x2() -> BinaryenOp; - fn BinaryenEqVecF32x4() -> BinaryenOp; - fn BinaryenNeVecF32x4() -> BinaryenOp; - fn BinaryenLtVecF32x4() -> BinaryenOp; - fn BinaryenGtVecF32x4() -> BinaryenOp; - fn BinaryenLeVecF32x4() -> BinaryenOp; - fn BinaryenGeVecF32x4() -> BinaryenOp; - fn BinaryenEqVecF64x2() -> BinaryenOp; - fn BinaryenNeVecF64x2() -> BinaryenOp; - fn BinaryenLtVecF64x2() -> BinaryenOp; - fn BinaryenGtVecF64x2() -> BinaryenOp; - fn BinaryenLeVecF64x2() -> BinaryenOp; - fn BinaryenGeVecF64x2() -> BinaryenOp; - fn BinaryenNotVec128() -> BinaryenOp; - fn BinaryenAndVec128() -> BinaryenOp; - fn BinaryenOrVec128() -> BinaryenOp; - fn BinaryenXorVec128() -> BinaryenOp; - fn BinaryenAndNotVec128() -> BinaryenOp; - fn BinaryenBitselectVec128() -> BinaryenOp; - fn BinaryenAnyTrueVec128() -> BinaryenOp; - fn BinaryenPopcntVecI8x16() -> BinaryenOp; - fn BinaryenAbsVecI8x16() -> BinaryenOp; - fn BinaryenNegVecI8x16() -> BinaryenOp; - fn BinaryenAllTrueVecI8x16() -> BinaryenOp; - fn BinaryenBitmaskVecI8x16() -> BinaryenOp; - fn BinaryenShlVecI8x16() -> BinaryenOp; - fn BinaryenShrSVecI8x16() -> BinaryenOp; - fn BinaryenShrUVecI8x16() -> BinaryenOp; - fn BinaryenAddVecI8x16() -> BinaryenOp; - fn BinaryenAddSatSVecI8x16() -> BinaryenOp; - fn BinaryenAddSatUVecI8x16() -> BinaryenOp; - fn BinaryenSubVecI8x16() -> BinaryenOp; - fn BinaryenSubSatSVecI8x16() -> BinaryenOp; - fn BinaryenSubSatUVecI8x16() -> BinaryenOp; - fn BinaryenMinSVecI8x16() -> BinaryenOp; - fn BinaryenMinUVecI8x16() -> BinaryenOp; - fn BinaryenMaxSVecI8x16() -> BinaryenOp; - fn BinaryenMaxUVecI8x16() -> BinaryenOp; - fn BinaryenAvgrUVecI8x16() -> BinaryenOp; - fn BinaryenAbsVecI16x8() -> BinaryenOp; - fn BinaryenNegVecI16x8() -> BinaryenOp; - fn BinaryenAllTrueVecI16x8() -> BinaryenOp; - fn BinaryenBitmaskVecI16x8() -> BinaryenOp; - fn BinaryenShlVecI16x8() -> BinaryenOp; - fn BinaryenShrSVecI16x8() -> BinaryenOp; - fn BinaryenShrUVecI16x8() -> BinaryenOp; - fn BinaryenAddVecI16x8() -> BinaryenOp; - fn BinaryenAddSatSVecI16x8() -> BinaryenOp; - fn BinaryenAddSatUVecI16x8() -> BinaryenOp; - fn BinaryenSubVecI16x8() -> BinaryenOp; - fn BinaryenSubSatSVecI16x8() -> BinaryenOp; - fn BinaryenSubSatUVecI16x8() -> BinaryenOp; - fn BinaryenMulVecI16x8() -> BinaryenOp; - fn BinaryenMinSVecI16x8() -> BinaryenOp; - fn BinaryenMinUVecI16x8() -> BinaryenOp; - fn BinaryenMaxSVecI16x8() -> BinaryenOp; - fn BinaryenMaxUVecI16x8() -> BinaryenOp; - fn BinaryenAvgrUVecI16x8() -> BinaryenOp; - fn BinaryenQ15MulrSatSVecI16x8() -> BinaryenOp; - fn BinaryenExtMulLowSVecI16x8() -> BinaryenOp; - fn BinaryenExtMulHighSVecI16x8() -> BinaryenOp; - fn BinaryenExtMulLowUVecI16x8() -> BinaryenOp; - fn BinaryenExtMulHighUVecI16x8() -> BinaryenOp; - fn BinaryenAbsVecI32x4() -> BinaryenOp; - fn BinaryenNegVecI32x4() -> BinaryenOp; - fn BinaryenAllTrueVecI32x4() -> BinaryenOp; - fn BinaryenBitmaskVecI32x4() -> BinaryenOp; - fn BinaryenShlVecI32x4() -> BinaryenOp; - fn BinaryenShrSVecI32x4() -> BinaryenOp; - fn BinaryenShrUVecI32x4() -> BinaryenOp; - fn BinaryenAddVecI32x4() -> BinaryenOp; - fn BinaryenSubVecI32x4() -> BinaryenOp; - fn BinaryenMulVecI32x4() -> BinaryenOp; - fn BinaryenMinSVecI32x4() -> BinaryenOp; - fn BinaryenMinUVecI32x4() -> BinaryenOp; - fn BinaryenMaxSVecI32x4() -> BinaryenOp; - fn BinaryenMaxUVecI32x4() -> BinaryenOp; - fn BinaryenDotSVecI16x8ToVecI32x4() -> BinaryenOp; - fn BinaryenExtMulLowSVecI32x4() -> BinaryenOp; - fn BinaryenExtMulHighSVecI32x4() -> BinaryenOp; - fn BinaryenExtMulLowUVecI32x4() -> BinaryenOp; - fn BinaryenExtMulHighUVecI32x4() -> BinaryenOp; - fn BinaryenAbsVecI64x2() -> BinaryenOp; - fn BinaryenNegVecI64x2() -> BinaryenOp; - fn BinaryenAllTrueVecI64x2() -> BinaryenOp; - fn BinaryenBitmaskVecI64x2() -> BinaryenOp; - fn BinaryenShlVecI64x2() -> BinaryenOp; - fn BinaryenShrSVecI64x2() -> BinaryenOp; - fn BinaryenShrUVecI64x2() -> BinaryenOp; - fn BinaryenAddVecI64x2() -> BinaryenOp; - fn BinaryenSubVecI64x2() -> BinaryenOp; - fn BinaryenMulVecI64x2() -> BinaryenOp; - fn BinaryenExtMulLowSVecI64x2() -> BinaryenOp; - fn BinaryenExtMulHighSVecI64x2() -> BinaryenOp; - fn BinaryenExtMulLowUVecI64x2() -> BinaryenOp; - fn BinaryenExtMulHighUVecI64x2() -> BinaryenOp; - fn BinaryenAbsVecF32x4() -> BinaryenOp; - fn BinaryenNegVecF32x4() -> BinaryenOp; - fn BinaryenSqrtVecF32x4() -> BinaryenOp; - fn BinaryenAddVecF32x4() -> BinaryenOp; - fn BinaryenSubVecF32x4() -> BinaryenOp; - fn BinaryenMulVecF32x4() -> BinaryenOp; - fn BinaryenDivVecF32x4() -> BinaryenOp; - fn BinaryenMinVecF32x4() -> BinaryenOp; - fn BinaryenMaxVecF32x4() -> BinaryenOp; - fn BinaryenPMinVecF32x4() -> BinaryenOp; - fn BinaryenPMaxVecF32x4() -> BinaryenOp; - fn BinaryenCeilVecF32x4() -> BinaryenOp; - fn BinaryenFloorVecF32x4() -> BinaryenOp; - fn BinaryenTruncVecF32x4() -> BinaryenOp; - fn BinaryenNearestVecF32x4() -> BinaryenOp; - fn BinaryenAbsVecF64x2() -> BinaryenOp; - fn BinaryenNegVecF64x2() -> BinaryenOp; - fn BinaryenSqrtVecF64x2() -> BinaryenOp; - fn BinaryenAddVecF64x2() -> BinaryenOp; - fn BinaryenSubVecF64x2() -> BinaryenOp; - fn BinaryenMulVecF64x2() -> BinaryenOp; - fn BinaryenDivVecF64x2() -> BinaryenOp; - fn BinaryenMinVecF64x2() -> BinaryenOp; - fn BinaryenMaxVecF64x2() -> BinaryenOp; - fn BinaryenPMinVecF64x2() -> BinaryenOp; - fn BinaryenPMaxVecF64x2() -> BinaryenOp; - fn BinaryenCeilVecF64x2() -> BinaryenOp; - fn BinaryenFloorVecF64x2() -> BinaryenOp; - fn BinaryenTruncVecF64x2() -> BinaryenOp; - fn BinaryenNearestVecF64x2() -> BinaryenOp; - fn BinaryenExtAddPairwiseSVecI8x16ToI16x8() -> BinaryenOp; - fn BinaryenExtAddPairwiseUVecI8x16ToI16x8() -> BinaryenOp; - fn BinaryenExtAddPairwiseSVecI16x8ToI32x4() -> BinaryenOp; - fn BinaryenExtAddPairwiseUVecI16x8ToI32x4() -> BinaryenOp; - fn BinaryenTruncSatSVecF32x4ToVecI32x4() -> BinaryenOp; - fn BinaryenTruncSatUVecF32x4ToVecI32x4() -> BinaryenOp; - fn BinaryenConvertSVecI32x4ToVecF32x4() -> BinaryenOp; - fn BinaryenConvertUVecI32x4ToVecF32x4() -> BinaryenOp; - fn BinaryenLoad8SplatVec128() -> BinaryenOp; - fn BinaryenLoad16SplatVec128() -> BinaryenOp; - fn BinaryenLoad32SplatVec128() -> BinaryenOp; - fn BinaryenLoad64SplatVec128() -> BinaryenOp; - fn BinaryenLoad8x8SVec128() -> BinaryenOp; - fn BinaryenLoad8x8UVec128() -> BinaryenOp; - fn BinaryenLoad16x4SVec128() -> BinaryenOp; - fn BinaryenLoad16x4UVec128() -> BinaryenOp; - fn BinaryenLoad32x2SVec128() -> BinaryenOp; - fn BinaryenLoad32x2UVec128() -> BinaryenOp; - fn BinaryenLoad32ZeroVec128() -> BinaryenOp; - fn BinaryenLoad64ZeroVec128() -> BinaryenOp; - fn BinaryenLoad8LaneVec128() -> BinaryenOp; - fn BinaryenLoad16LaneVec128() -> BinaryenOp; - fn BinaryenLoad32LaneVec128() -> BinaryenOp; - fn BinaryenLoad64LaneVec128() -> BinaryenOp; - fn BinaryenStore8LaneVec128() -> BinaryenOp; - fn BinaryenStore16LaneVec128() -> BinaryenOp; - fn BinaryenStore32LaneVec128() -> BinaryenOp; - fn BinaryenStore64LaneVec128() -> BinaryenOp; - fn BinaryenNarrowSVecI16x8ToVecI8x16() -> BinaryenOp; - fn BinaryenNarrowUVecI16x8ToVecI8x16() -> BinaryenOp; - fn BinaryenNarrowSVecI32x4ToVecI16x8() -> BinaryenOp; - fn BinaryenNarrowUVecI32x4ToVecI16x8() -> BinaryenOp; - fn BinaryenExtendLowSVecI8x16ToVecI16x8() -> BinaryenOp; - fn BinaryenExtendHighSVecI8x16ToVecI16x8() -> BinaryenOp; - fn BinaryenExtendLowUVecI8x16ToVecI16x8() -> BinaryenOp; - fn BinaryenExtendHighUVecI8x16ToVecI16x8() -> BinaryenOp; - fn BinaryenExtendLowSVecI16x8ToVecI32x4() -> BinaryenOp; - fn BinaryenExtendHighSVecI16x8ToVecI32x4() -> BinaryenOp; - fn BinaryenExtendLowUVecI16x8ToVecI32x4() -> BinaryenOp; - fn BinaryenExtendHighUVecI16x8ToVecI32x4() -> BinaryenOp; - fn BinaryenExtendLowSVecI32x4ToVecI64x2() -> BinaryenOp; - fn BinaryenExtendHighSVecI32x4ToVecI64x2() -> BinaryenOp; - fn BinaryenExtendLowUVecI32x4ToVecI64x2() -> BinaryenOp; - fn BinaryenExtendHighUVecI32x4ToVecI64x2() -> BinaryenOp; - fn BinaryenConvertLowSVecI32x4ToVecF64x2() -> BinaryenOp; - fn BinaryenConvertLowUVecI32x4ToVecF64x2() -> BinaryenOp; - fn BinaryenTruncSatZeroSVecF64x2ToVecI32x4() -> BinaryenOp; - fn BinaryenTruncSatZeroUVecF64x2ToVecI32x4() -> BinaryenOp; - fn BinaryenDemoteZeroVecF64x2ToVecF32x4() -> BinaryenOp; - fn BinaryenPromoteLowVecF32x4ToVecF64x2() -> BinaryenOp; - fn BinaryenSwizzleVec8x16() -> BinaryenOp; - fn BinaryenRefIsNull() -> BinaryenOp; - fn BinaryenRefIsFunc() -> BinaryenOp; - fn BinaryenRefIsData() -> BinaryenOp; - fn BinaryenRefIsI31() -> BinaryenOp; - fn BinaryenRefAsNonNull() -> BinaryenOp; - fn BinaryenRefAsFunc() -> BinaryenOp; - fn BinaryenRefAsData() -> BinaryenOp; - fn BinaryenRefAsI31() -> BinaryenOp; - - fn BinaryenAddGlobal( - module: BinaryenModule, - name: *const c_char, - ty: BinaryenType, - mutable: bool, - init: BinaryenExpression, - ) -> BinaryenGlobal; - fn BinaryenGetNumGlobals(module: BinaryenModule) -> BinaryenIndex; - - fn BinaryenAddTable( - module: BinaryenModule, - name: *const c_char, - initial: BinaryenIndex, - max: BinaryenIndex, - ty: BinaryenType, - ) -> BinaryenTable; - fn BinaryenGetNumTables(module: BinaryenModule) -> BinaryenIndex; - - fn BinaryenAddActiveElementSegment( - module: BinaryenModule, - table: *const c_char, - name: *const c_char, - func_names: *const *const c_char, - num_funcs: BinaryenIndex, - offset: BinaryenExpression, - ) -> BinaryenElementSegment; - - fn BinaryenSetMemory( - module: BinaryenModule, - init: BinaryenIndex, - max: BinaryenIndex, - export_name: *const c_char, - segments: *const *const c_char, - seg_passive: *const bool, - seg_offsets: *const BinaryenExpression, - sizes: *const BinaryenIndex, - n_segments: BinaryenIndex, - shared: bool, - ); - - fn BinaryenAddTableImport( - module: BinaryenModule, - name: *const c_char, - extern_module: *const c_char, - extern_name: *const c_char, - ); - fn BinaryenAddMemoryImport( - module: BinaryenModule, - name: *const c_char, - extern_module: *const c_char, - extern_name: *const c_char, - ); - fn BinaryenAddGlobalImport( - module: BinaryenModule, - name: *const c_char, - extern_module: *const c_char, - extern_name: *const c_char, - ty: BinaryenType, - mutable: bool, - ); - fn BinaryenAddFunctionImport( - module: BinaryenModule, - name: *const c_char, - extern_module: *const c_char, - extern_name: *const c_char, - params: BinaryenType, - results: BinaryenType, - ); - - fn BinaryenGlobalGetName(global: BinaryenGlobal) -> *const c_char; - fn BinaryenGetGlobalByIndex(module: BinaryenModule, index: BinaryenIndex) -> BinaryenGlobal; - - fn BinaryenAddTableExport( - module: BinaryenModule, - internal: *const c_char, - external: *const c_char, - ); - fn BinaryenAddFunctionExport( - module: BinaryenModule, - internal: *const c_char, - external: *const c_char, - ); - fn BinaryenAddGlobalExport( - module: BinaryenModule, - internal: *const c_char, - external: *const c_char, - ); - fn BinaryenAddMemoryExport( - module: BinaryenModule, - internal: *const c_char, - external: *const c_char, - ); -} - -#[repr(C)] -struct BinaryenLiteral { - _pad0: usize, - _pad1: [u8; 16], -} - -type BinaryenOp = i32;