//! 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<Module> { 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<Vec<u8>> { 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<Module> { 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<u64>) -> 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<u32>) -> 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<usize>, 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::<Vec<_>>(); let seg_data = segments .iter() .map(|seg| seg.data.as_ptr() as *const c_char) .collect::<Vec<_>>(); let seg_size = segments .iter() .map(|seg| seg.data.len() as BinaryenIndex) .collect::<Vec<_>>(); // 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<Expression> { 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<Item = ir::Type>, results: impl Iterator<Item = ir::Type>, locals: impl Iterator<Item = ir::Type>, body: Expression, ) -> Function { let params = tys_to_binaryen(params); let results = tys_to_binaryen(results); let locals: Vec<BinaryenType> = 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<ir::Type> 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<Item = ir::Type>) -> BinaryenType { let tys: Vec<BinaryenType> = 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<String> { 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::<Vec<_>>(); 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::<Vec<_>>(); 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::<Vec<_>>(); 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::<Vec<_>>(); 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;