Lines
93.7 %
Functions
41.51 %
Branches
100 %
use wasm_encoder::{BlockType, Encode, Function, HeapType, Instruction, MemArg, ValType};
pub struct FunctionEmitter {
bytes: Vec<u8>,
}
impl FunctionEmitter {
pub fn new() -> Self {
Self { bytes: Vec::new() }
pub fn finish(self, locals: &[(u32, ValType)]) -> Function {
let mut func = Function::new(locals.iter().copied());
func.raw(self.bytes);
func
pub fn memory_init(&mut self, data_idx: u32, dst: u32, len: u32) {
Instruction::I32Const(dst as i32).encode(&mut self.bytes);
Instruction::I32Const(0).encode(&mut self.bytes);
Instruction::I32Const(len as i32).encode(&mut self.bytes);
Instruction::MemoryInit {
mem: 0,
data_index: data_idx,
.encode(&mut self.bytes);
pub fn local_get(&mut self, idx: u32) {
Instruction::LocalGet(idx).encode(&mut self.bytes);
pub fn local_set(&mut self, idx: u32) {
Instruction::LocalSet(idx).encode(&mut self.bytes);
pub fn local_tee(&mut self, idx: u32) {
Instruction::LocalTee(idx).encode(&mut self.bytes);
pub fn i32_const(&mut self, value: i32) {
Instruction::I32Const(value).encode(&mut self.bytes);
pub fn i64_const(&mut self, value: i64) {
Instruction::I64Const(value).encode(&mut self.bytes);
pub fn i32_add(&mut self) {
Instruction::I32Add.encode(&mut self.bytes);
pub fn i32_sub(&mut self) {
Instruction::I32Sub.encode(&mut self.bytes);
pub fn i32_eqz(&mut self) {
Instruction::I32Eqz.encode(&mut self.bytes);
pub fn i32_eq(&mut self) {
Instruction::I32Eq.encode(&mut self.bytes);
pub fn i32_lt_s(&mut self) {
Instruction::I32LtS.encode(&mut self.bytes);
pub fn i32_ge_s(&mut self) {
Instruction::I32GeS.encode(&mut self.bytes);
pub fn i32_gt_s(&mut self) {
Instruction::I32GtS.encode(&mut self.bytes);
pub fn i32_le_s(&mut self) {
Instruction::I32LeS.encode(&mut self.bytes);
pub fn i32_ne(&mut self) {
Instruction::I32Ne.encode(&mut self.bytes);
pub fn i32_shl(&mut self) {
Instruction::I32Shl.encode(&mut self.bytes);
pub fn i32_or(&mut self) {
Instruction::I32Or.encode(&mut self.bytes);
pub fn i64_ne(&mut self) {
Instruction::I64Ne.encode(&mut self.bytes);
pub fn i32_mul(&mut self) {
Instruction::I32Mul.encode(&mut self.bytes);
pub fn i32_load(&mut self, offset: u64) {
Instruction::I32Load(MemArg {
offset,
align: 2,
memory_index: 0,
})
pub fn i32_load8_u(&mut self, offset: u64) {
Instruction::I32Load8U(MemArg {
align: 0,
pub fn i64_load(&mut self, offset: u64) {
Instruction::I64Load(MemArg {
align: 3,
pub fn i32_ge_u(&mut self) {
Instruction::I32GeU.encode(&mut self.bytes);
pub fn struct_get(&mut self, type_idx: u32, field_idx: u32) {
Instruction::StructGet {
struct_type_index: type_idx,
field_index: field_idx,
pub fn if_block(&mut self, block_type: BlockType) {
Instruction::If(block_type).encode(&mut self.bytes);
pub fn else_block(&mut self) {
Instruction::Else.encode(&mut self.bytes);
pub fn i32_store_raw(&mut self) {
Instruction::I32Store(MemArg {
offset: 0,
pub fn i64_store_raw(&mut self) {
Instruction::I64Store(MemArg {
pub fn i64_extend_i32_u(&mut self) {
Instruction::I64ExtendI32U.encode(&mut self.bytes);
pub fn i32_wrap_i64(&mut self) {
Instruction::I32WrapI64.encode(&mut self.bytes);
pub fn array_new_data(&mut self, type_idx: u32, data_idx: u32) {
Instruction::ArrayNewData {
array_type_index: type_idx,
array_data_index: data_idx,
pub fn array_get_u(&mut self, type_idx: u32) {
Instruction::ArrayGetU(type_idx).encode(&mut self.bytes);
pub fn array_new_default(&mut self, type_idx: u32) {
Instruction::ArrayNewDefault(type_idx).encode(&mut self.bytes);
pub fn array_set(&mut self, type_idx: u32) {
Instruction::ArraySet(type_idx).encode(&mut self.bytes);
pub fn array_len(&mut self) {
Instruction::ArrayLen.encode(&mut self.bytes);
pub fn block_start(&mut self) {
Instruction::Block(BlockType::Empty).encode(&mut self.bytes);
pub fn loop_start(&mut self) {
Instruction::Loop(BlockType::Empty).encode(&mut self.bytes);
pub fn block_end(&mut self) {
Instruction::End.encode(&mut self.bytes);
pub fn br(&mut self, depth: u32) {
Instruction::Br(depth).encode(&mut self.bytes);
pub fn br_if(&mut self, depth: u32) {
Instruction::BrIf(depth).encode(&mut self.bytes);
pub fn call(&mut self, func_idx: u32) {
Instruction::Call(func_idx).encode(&mut self.bytes);
pub fn store_u8_dynamic(&mut self, local_base: u32, offset: u32, value: u8) {
Instruction::LocalGet(local_base).encode(&mut self.bytes);
Instruction::I32Const(offset as i32).encode(&mut self.bytes);
Instruction::I32Const(i32::from(value)).encode(&mut self.bytes);
Instruction::I32Store8(MemArg {
pub fn store_i32_dynamic(&mut self, local_base: u32, offset: u32, value: i32) {
pub fn store_i64_dynamic(&mut self, local_base: u32, offset: u32, value: i64) {
pub fn i32_store8_raw(&mut self) {
pub fn i32_load16_u(&mut self, offset: u64) {
Instruction::I32Load16U(MemArg {
align: 1,
pub fn struct_new(&mut self, type_idx: u32) {
Instruction::StructNew(type_idx).encode(&mut self.bytes);
pub fn ref_null(&mut self, type_idx: u32) {
Instruction::RefNull(HeapType::Concrete(type_idx)).encode(&mut self.bytes);
pub fn ref_is_null(&mut self) {
Instruction::RefIsNull.encode(&mut self.bytes);
pub fn end(&mut self) {
impl Default for FunctionEmitter {
fn default() -> Self {
Self::new()