use std::collections::HashMap; use std::mem::transmute; use crate::leb::{ write_fixed_leb16_at_idx, write_fixed_leb32_at_idx, write_leb_i32, write_leb_i64, write_leb_u32, }; use crate::wasmgen::wasm_opcodes as op; pub trait SafeToU8 { fn safe_to_u8(self) -> u8; } impl SafeToU8 for usize { fn safe_to_u8(self) -> u8 { dbg_assert!(self <= ::std::u8::MAX as usize); self as u8 } } pub trait SafeToU16 { fn safe_to_u16(self) -> u16; } impl SafeToU16 for usize { fn safe_to_u16(self) -> u16 { dbg_assert!(self <= ::std::u16::MAX as usize); self as u16 } } #[derive(PartialEq)] #[allow(non_camel_case_types)] enum FunctionType { FN0, FN1, FN2, FN3, FN0_RET, FN0_RET_I64, FN1_RET, FN2_RET, FN1_RET_I64, FN1_F32_RET, FN1_F64_RET, FN2_I32_I64, FN2_I64_I32, FN2_I64_I32_RET, FN2_I64_I32_RET_I64, FN2_F32_I32, FN3_RET, FN3_I64_I32_I32, FN3_I32_I64_I32, FN3_I32_I64_I32_RET, FN4_I32_I64_I64_I32_RET, // When adding at the end, update LAST below } impl FunctionType { pub fn of_u8(x: u8) -> FunctionType { dbg_assert!(x <= FunctionType::LAST as u8); unsafe { transmute(x) } } pub fn to_u8(self: FunctionType) -> u8 { self as u8 } pub const LAST: FunctionType = FunctionType::FN4_I32_I64_I64_I32_RET; } pub const WASM_MODULE_ARGUMENT_COUNT: u8 = 1; pub struct WasmBuilder { output: Vec, instruction_body: Vec, idx_import_table_size: usize, // for rewriting once finished idx_import_count: usize, // for rewriting once finished idx_import_entries: usize, // for searching the imports import_table_size: usize, // the current import table size (to avoid reading 2 byte leb) import_count: u16, // same as above initial_static_size: usize, // size of module after initialization, rest is drained on reset // label for referencing block/if/loop constructs directly via branch instructions next_label: Label, label_stack: Vec