use wasm_encoder::ValType;
pub(super) fn emit_chunked_blocking_write(
f: &mut wasm_encoder::Function,
len_local: u32,
off_local: u32,
write_fn: u32,
push_handle: &dyn Fn(&mut wasm_encoder::Function),
push_retptr: &dyn Fn(&mut wasm_encoder::Function),
on_chunk_err: Option<&dyn Fn(&mut wasm_encoder::Function)>,
) {
use wasm_encoder::{BlockType, Instruction, MemArg};
let mem1 = MemArg {
offset: 0,
align: 0,
memory_index: 0,
};
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::LocalSet(off_local));
f.instruction(&Instruction::Block(BlockType::Empty));
f.instruction(&Instruction::Loop(BlockType::Empty));
f.instruction(&Instruction::LocalGet(len_local));
f.instruction(&Instruction::LocalGet(off_local));
f.instruction(&Instruction::I32Sub);
f.instruction(&Instruction::I32Eqz);
f.instruction(&Instruction::BrIf(1));
push_handle(f);
f.instruction(&Instruction::LocalGet(off_local));
f.instruction(&Instruction::LocalGet(len_local));
f.instruction(&Instruction::LocalGet(off_local));
f.instruction(&Instruction::I32Sub);
f.instruction(&Instruction::I32Const(4096));
f.instruction(&Instruction::LocalGet(len_local));
f.instruction(&Instruction::LocalGet(off_local));
f.instruction(&Instruction::I32Sub);
f.instruction(&Instruction::I32Const(4096));
f.instruction(&Instruction::I32LtU);
f.instruction(&Instruction::Select);
push_retptr(f);
f.instruction(&Instruction::Call(write_fn));
if let Some(handler) = on_chunk_err {
push_retptr(f);
f.instruction(&Instruction::I32Load8U(mem1));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::I32Ne);
f.instruction(&Instruction::If(BlockType::Empty));
handler(f);
f.instruction(&Instruction::End);
}
f.instruction(&Instruction::LocalGet(off_local));
f.instruction(&Instruction::LocalGet(len_local));
f.instruction(&Instruction::LocalGet(off_local));
f.instruction(&Instruction::I32Sub);
f.instruction(&Instruction::I32Const(4096));
f.instruction(&Instruction::LocalGet(len_local));
f.instruction(&Instruction::LocalGet(off_local));
f.instruction(&Instruction::I32Sub);
f.instruction(&Instruction::I32Const(4096));
f.instruction(&Instruction::I32LtU);
f.instruction(&Instruction::Select);
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::LocalSet(off_local));
f.instruction(&Instruction::Br(0));
f.instruction(&Instruction::End); f.instruction(&Instruction::End); }
pub(super) struct CabiReallocIndices {
pub(super) fn_type: u32,
pub(super) fn_idx: u32,
}
pub(super) struct DecodeListStringIndices {
pub(super) fn_type: u32,
pub(super) fn_idx: u32,
pub(super) string_type_idx: u32,
pub(super) list_string_type_idx: u32,
}
pub(super) struct EnvGetLookupIndices {
pub(super) fn_type: u32,
pub(super) fn_idx: u32,
pub(super) string_type_idx: u32,
pub(super) option_string_type_idx: u32,
}
pub(super) struct FormatIso8601Indices {
pub(super) fn_type: u32,
pub(super) fn_idx: u32,
pub(super) string_type_idx: u32,
}
pub(super) struct ConsoleReadLineIndices {
pub(super) fn_type: u32,
pub(super) fn_idx: u32,
pub(super) string_type_idx: u32,
pub(super) result_string_string_type_idx: u32,
}
pub(super) struct TimeSleepIndices {
pub(super) fn_type: u32,
pub(super) fn_idx: u32,
}
pub(super) struct DiskExistsIndices {
pub(super) fn_type: u32,
pub(super) fn_idx: u32,
}
pub(super) struct DiskReadTextIndices {
pub(super) fn_type: u32,
pub(super) fn_idx: u32,
pub(super) string_type_idx: u32,
pub(super) result_string_string_type_idx: u32,
}
pub(super) struct DiskWriteTextIndices {
pub(super) fn_type: u32,
pub(super) fn_idx: u32,
pub(super) string_type_idx: u32,
pub(super) result_unit_string_type_idx: u32,
}
pub(super) struct DiskSimplePathOpIndices {
pub(super) fn_type: u32,
pub(super) fn_idx: u32,
pub(super) string_type_idx: u32,
pub(super) result_unit_string_type_idx: u32,
}
pub(super) struct DiskListDirIndices {
pub(super) fn_type: u32,
pub(super) fn_idx: u32,
pub(super) string_type_idx: u32,
pub(super) list_string_type_idx: u32,
pub(super) result_list_string_string_type_idx: u32,
}
pub(super) fn emit_cabi_realloc(bump_global: u32) -> wasm_encoder::Function {
use wasm_encoder::{BlockType, Function, Instruction, MemArg};
let mut f = Function::new(vec![(2, ValType::I32)]);
let p_old_ptr = 0u32;
let p_old_size = 1u32;
let p_align = 2u32;
let p_new_size = 3u32;
let l_aligned = 4u32;
let l_end = 5u32;
f.instruction(&Instruction::GlobalGet(bump_global));
f.instruction(&Instruction::LocalGet(p_align));
f.instruction(&Instruction::I32Const(1));
f.instruction(&Instruction::I32Sub);
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::LocalGet(p_align));
f.instruction(&Instruction::I32Const(1));
f.instruction(&Instruction::I32Sub);
f.instruction(&Instruction::I32Const(-1));
f.instruction(&Instruction::I32Xor);
f.instruction(&Instruction::I32And);
f.instruction(&Instruction::LocalSet(l_aligned));
f.instruction(&Instruction::LocalGet(l_aligned));
f.instruction(&Instruction::LocalGet(p_new_size));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::LocalSet(l_end));
f.instruction(&Instruction::LocalGet(l_end));
f.instruction(&Instruction::MemorySize(0));
f.instruction(&Instruction::I32Const(16));
f.instruction(&Instruction::I32Shl); f.instruction(&Instruction::I32GtU);
f.instruction(&Instruction::If(BlockType::Empty));
{
f.instruction(&Instruction::LocalGet(l_end));
f.instruction(&Instruction::I32Const(65535));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::I32Const(16));
f.instruction(&Instruction::I32ShrU);
f.instruction(&Instruction::MemorySize(0));
f.instruction(&Instruction::I32Sub);
f.instruction(&Instruction::MemoryGrow(0));
f.instruction(&Instruction::Drop); }
f.instruction(&Instruction::End);
f.instruction(&Instruction::LocalGet(p_old_ptr));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::I32Ne);
f.instruction(&Instruction::LocalGet(p_old_size));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::I32GtU);
f.instruction(&Instruction::I32And);
f.instruction(&Instruction::If(BlockType::Empty));
{
f.instruction(&Instruction::LocalGet(l_aligned));
f.instruction(&Instruction::LocalGet(p_old_ptr));
f.instruction(&Instruction::LocalGet(p_old_size));
f.instruction(&Instruction::LocalGet(p_new_size));
f.instruction(&Instruction::LocalGet(p_old_size));
f.instruction(&Instruction::LocalGet(p_new_size));
f.instruction(&Instruction::I32LtU);
f.instruction(&Instruction::Select);
let _ = MemArg {
offset: 0,
align: 0,
memory_index: 0,
}; f.instruction(&Instruction::MemoryCopy {
src_mem: 0,
dst_mem: 0,
});
}
f.instruction(&Instruction::End);
f.instruction(&Instruction::LocalGet(l_end));
f.instruction(&Instruction::GlobalSet(bump_global));
f.instruction(&Instruction::LocalGet(l_aligned));
f.instruction(&Instruction::End);
f
}
pub(super) fn emit_decode_list_string(
string_type_idx: u32,
list_string_type_idx: u32,
) -> wasm_encoder::Function {
use wasm_encoder::{BlockType, Function, HeapType, Instruction, MemArg, RefType};
let s_ref = ValType::Ref(RefType {
nullable: true,
heap_type: HeapType::Concrete(string_type_idx),
});
let l_ref = ValType::Ref(RefType {
nullable: true,
heap_type: HeapType::Concrete(list_string_type_idx),
});
let mut f = Function::new(vec![
(7, ValType::I32), (1, s_ref), (1, l_ref), ]);
let p_retptr = 0u32;
let l_list_ptr = 1u32;
let l_list_len = 2u32;
let l_i = 3u32;
let l_entry_ptr = 4u32;
let l_str_ptr = 5u32;
let l_str_len = 6u32;
let l_j = 7u32;
let l_arr = 8u32;
let l_acc = 9u32;
let mem4 = MemArg {
offset: 0,
align: 2,
memory_index: 0,
};
let mem4_off4 = MemArg {
offset: 4,
align: 2,
memory_index: 0,
};
let mem1 = MemArg {
offset: 0,
align: 0,
memory_index: 0,
};
f.instruction(&Instruction::LocalGet(p_retptr));
f.instruction(&Instruction::I32Load(mem4));
f.instruction(&Instruction::LocalSet(l_list_ptr));
f.instruction(&Instruction::LocalGet(p_retptr));
f.instruction(&Instruction::I32Load(mem4_off4));
f.instruction(&Instruction::LocalSet(l_list_len));
f.instruction(&Instruction::RefNull(HeapType::Concrete(
list_string_type_idx,
)));
f.instruction(&Instruction::LocalSet(l_acc));
f.instruction(&Instruction::LocalGet(l_list_len));
f.instruction(&Instruction::I32Const(1));
f.instruction(&Instruction::I32Sub);
f.instruction(&Instruction::LocalSet(l_i));
f.instruction(&Instruction::Block(BlockType::Empty));
f.instruction(&Instruction::Loop(BlockType::Empty));
f.instruction(&Instruction::LocalGet(l_i));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::I32LtS);
f.instruction(&Instruction::BrIf(1));
f.instruction(&Instruction::LocalGet(l_list_ptr));
f.instruction(&Instruction::LocalGet(l_i));
f.instruction(&Instruction::I32Const(3));
f.instruction(&Instruction::I32Shl);
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::LocalSet(l_entry_ptr));
f.instruction(&Instruction::LocalGet(l_entry_ptr));
f.instruction(&Instruction::I32Load(mem4));
f.instruction(&Instruction::LocalSet(l_str_ptr));
f.instruction(&Instruction::LocalGet(l_entry_ptr));
f.instruction(&Instruction::I32Load(mem4_off4));
f.instruction(&Instruction::LocalSet(l_str_len));
f.instruction(&Instruction::LocalGet(l_str_len));
f.instruction(&Instruction::ArrayNewDefault(string_type_idx));
f.instruction(&Instruction::LocalSet(l_arr));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::LocalSet(l_j));
f.instruction(&Instruction::Block(BlockType::Empty));
f.instruction(&Instruction::Loop(BlockType::Empty));
f.instruction(&Instruction::LocalGet(l_j));
f.instruction(&Instruction::LocalGet(l_str_len));
f.instruction(&Instruction::I32GeU);
f.instruction(&Instruction::BrIf(1));
f.instruction(&Instruction::LocalGet(l_arr));
f.instruction(&Instruction::LocalGet(l_j));
f.instruction(&Instruction::LocalGet(l_str_ptr));
f.instruction(&Instruction::LocalGet(l_j));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::I32Load8U(mem1));
f.instruction(&Instruction::ArraySet(string_type_idx));
f.instruction(&Instruction::LocalGet(l_j));
f.instruction(&Instruction::I32Const(1));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::LocalSet(l_j));
f.instruction(&Instruction::Br(0));
f.instruction(&Instruction::End); f.instruction(&Instruction::End);
f.instruction(&Instruction::LocalGet(l_arr));
f.instruction(&Instruction::LocalGet(l_acc));
f.instruction(&Instruction::StructNew(list_string_type_idx));
f.instruction(&Instruction::LocalSet(l_acc));
f.instruction(&Instruction::LocalGet(l_i));
f.instruction(&Instruction::I32Const(1));
f.instruction(&Instruction::I32Sub);
f.instruction(&Instruction::LocalSet(l_i));
f.instruction(&Instruction::Br(0));
f.instruction(&Instruction::End); f.instruction(&Instruction::End);
f.instruction(&Instruction::LocalGet(l_acc));
f.instruction(&Instruction::End); f
}
pub(super) fn emit_env_get_lookup(
string_type_idx: u32,
option_string_type_idx: u32,
) -> wasm_encoder::Function {
use wasm_encoder::{BlockType, Function, HeapType, Instruction, MemArg, RefType};
let s_ref = ValType::Ref(RefType {
nullable: true,
heap_type: HeapType::Concrete(string_type_idx),
});
let mut f = Function::new(vec![
(8, ValType::I32), (1, s_ref), ]);
let p_retptr = 0u32;
let p_key_ptr = 1u32;
let p_key_len = 2u32;
let l_list_ptr = 3u32;
let l_list_len = 4u32;
let l_i = 5u32;
let l_entry_ptr = 6u32;
let l_e_key_ptr = 7u32;
let l_e_key_len = 8u32;
let l_j = 9u32;
let l_mismatch = 10u32;
let l_arr = 11u32;
let mem4 = MemArg {
offset: 0,
align: 2,
memory_index: 0,
};
let mem4_o4 = MemArg {
offset: 4,
align: 2,
memory_index: 0,
};
let mem4_o8 = MemArg {
offset: 8,
align: 2,
memory_index: 0,
};
let mem4_o12 = MemArg {
offset: 12,
align: 2,
memory_index: 0,
};
let mem1 = MemArg {
offset: 0,
align: 0,
memory_index: 0,
};
f.instruction(&Instruction::LocalGet(p_retptr));
f.instruction(&Instruction::I32Load(mem4));
f.instruction(&Instruction::LocalSet(l_list_ptr));
f.instruction(&Instruction::LocalGet(p_retptr));
f.instruction(&Instruction::I32Load(mem4_o4));
f.instruction(&Instruction::LocalSet(l_list_len));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::LocalSet(l_i));
f.instruction(&Instruction::Block(BlockType::Empty));
f.instruction(&Instruction::Loop(BlockType::Empty));
f.instruction(&Instruction::LocalGet(l_i));
f.instruction(&Instruction::LocalGet(l_list_len));
f.instruction(&Instruction::I32GeU);
f.instruction(&Instruction::BrIf(1));
f.instruction(&Instruction::LocalGet(l_list_ptr));
f.instruction(&Instruction::LocalGet(l_i));
f.instruction(&Instruction::I32Const(4));
f.instruction(&Instruction::I32Shl);
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::LocalSet(l_entry_ptr));
f.instruction(&Instruction::LocalGet(l_entry_ptr));
f.instruction(&Instruction::I32Load(mem4));
f.instruction(&Instruction::LocalSet(l_e_key_ptr));
f.instruction(&Instruction::LocalGet(l_entry_ptr));
f.instruction(&Instruction::I32Load(mem4_o4));
f.instruction(&Instruction::LocalSet(l_e_key_len));
f.instruction(&Instruction::LocalGet(l_e_key_len));
f.instruction(&Instruction::LocalGet(p_key_len));
f.instruction(&Instruction::I32Ne);
f.instruction(&Instruction::If(BlockType::Empty));
{
f.instruction(&Instruction::LocalGet(l_i));
f.instruction(&Instruction::I32Const(1));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::LocalSet(l_i));
f.instruction(&Instruction::Br(1));
}
f.instruction(&Instruction::End);
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::LocalSet(l_mismatch));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::LocalSet(l_j));
f.instruction(&Instruction::Block(BlockType::Empty));
f.instruction(&Instruction::Loop(BlockType::Empty));
f.instruction(&Instruction::LocalGet(l_j));
f.instruction(&Instruction::LocalGet(p_key_len));
f.instruction(&Instruction::I32GeU);
f.instruction(&Instruction::BrIf(1));
f.instruction(&Instruction::LocalGet(p_key_ptr));
f.instruction(&Instruction::LocalGet(l_j));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::I32Load8U(mem1));
f.instruction(&Instruction::LocalGet(l_e_key_ptr));
f.instruction(&Instruction::LocalGet(l_j));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::I32Load8U(mem1));
f.instruction(&Instruction::I32Ne);
f.instruction(&Instruction::If(BlockType::Empty));
{
f.instruction(&Instruction::I32Const(1));
f.instruction(&Instruction::LocalSet(l_mismatch));
f.instruction(&Instruction::Br(2)); }
f.instruction(&Instruction::End);
f.instruction(&Instruction::LocalGet(l_j));
f.instruction(&Instruction::I32Const(1));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::LocalSet(l_j));
f.instruction(&Instruction::Br(0));
f.instruction(&Instruction::End); f.instruction(&Instruction::End);
f.instruction(&Instruction::LocalGet(l_mismatch));
f.instruction(&Instruction::I32Eqz);
f.instruction(&Instruction::If(BlockType::Empty));
{
f.instruction(&Instruction::LocalGet(l_entry_ptr));
f.instruction(&Instruction::I32Load(mem4_o8));
f.instruction(&Instruction::LocalSet(l_e_key_ptr)); f.instruction(&Instruction::LocalGet(l_entry_ptr));
f.instruction(&Instruction::I32Load(mem4_o12));
f.instruction(&Instruction::LocalSet(l_e_key_len));
f.instruction(&Instruction::LocalGet(l_e_key_len));
f.instruction(&Instruction::ArrayNewDefault(string_type_idx));
f.instruction(&Instruction::LocalSet(l_arr));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::LocalSet(l_j));
f.instruction(&Instruction::Block(BlockType::Empty));
f.instruction(&Instruction::Loop(BlockType::Empty));
f.instruction(&Instruction::LocalGet(l_j));
f.instruction(&Instruction::LocalGet(l_e_key_len));
f.instruction(&Instruction::I32GeU);
f.instruction(&Instruction::BrIf(1));
f.instruction(&Instruction::LocalGet(l_arr));
f.instruction(&Instruction::LocalGet(l_j));
f.instruction(&Instruction::LocalGet(l_e_key_ptr));
f.instruction(&Instruction::LocalGet(l_j));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::I32Load8U(mem1));
f.instruction(&Instruction::ArraySet(string_type_idx));
f.instruction(&Instruction::LocalGet(l_j));
f.instruction(&Instruction::I32Const(1));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::LocalSet(l_j));
f.instruction(&Instruction::Br(0));
f.instruction(&Instruction::End); f.instruction(&Instruction::End);
f.instruction(&Instruction::I32Const(1));
f.instruction(&Instruction::LocalGet(l_arr));
f.instruction(&Instruction::StructNew(option_string_type_idx));
f.instruction(&Instruction::Return);
}
f.instruction(&Instruction::End);
f.instruction(&Instruction::LocalGet(l_i));
f.instruction(&Instruction::I32Const(1));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::LocalSet(l_i));
f.instruction(&Instruction::Br(0));
f.instruction(&Instruction::End); f.instruction(&Instruction::End);
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::RefNull(HeapType::Concrete(string_type_idx)));
f.instruction(&Instruction::StructNew(option_string_type_idx));
f.instruction(&Instruction::End); f
}
pub(super) fn emit_format_iso8601(string_type_idx: u32) -> wasm_encoder::Function {
use wasm_encoder::{Function, HeapType, Instruction, RefType};
let s_ref = ValType::Ref(RefType {
nullable: true,
heap_type: HeapType::Concrete(string_type_idx),
});
let mut f = Function::new(vec![
(8, ValType::I64), (11, ValType::I32), (1, s_ref), ]);
let p_secs = 0u32;
let p_nanos = 1u32;
let l_z = 2u32;
let l_era = 3u32;
let l_doe = 4u32;
let l_yoe = 5u32;
let l_y = 6u32;
let l_doy = 7u32;
let l_mp_i64 = 8u32;
let l_days = 9u32;
let l_hour = 10u32;
let l_minute = 11u32;
let l_second = 12u32;
let l_ms = 13u32;
let l_mp = 14u32;
let l_day = 15u32;
let l_month = 16u32;
let l_year = 17u32;
let l_sod = 18u32;
let l_arr = 21u32;
f.instruction(&Instruction::LocalGet(p_secs));
f.instruction(&Instruction::I64Const(86_400));
f.instruction(&Instruction::I64DivS);
f.instruction(&Instruction::LocalSet(l_days));
f.instruction(&Instruction::LocalGet(p_secs));
f.instruction(&Instruction::I64Const(86_400));
f.instruction(&Instruction::I64RemS);
f.instruction(&Instruction::I32WrapI64);
f.instruction(&Instruction::LocalSet(l_sod));
f.instruction(&Instruction::LocalGet(l_sod));
f.instruction(&Instruction::I32Const(3_600));
f.instruction(&Instruction::I32DivU);
f.instruction(&Instruction::LocalSet(l_hour));
f.instruction(&Instruction::LocalGet(l_sod));
f.instruction(&Instruction::I32Const(3_600));
f.instruction(&Instruction::I32RemU);
f.instruction(&Instruction::I32Const(60));
f.instruction(&Instruction::I32DivU);
f.instruction(&Instruction::LocalSet(l_minute));
f.instruction(&Instruction::LocalGet(l_sod));
f.instruction(&Instruction::I32Const(60));
f.instruction(&Instruction::I32RemU);
f.instruction(&Instruction::LocalSet(l_second));
f.instruction(&Instruction::LocalGet(p_nanos));
f.instruction(&Instruction::I32Const(1_000_000));
f.instruction(&Instruction::I32DivU);
f.instruction(&Instruction::LocalSet(l_ms));
f.instruction(&Instruction::LocalGet(l_days));
f.instruction(&Instruction::I64Const(719_468));
f.instruction(&Instruction::I64Add);
f.instruction(&Instruction::LocalSet(l_z));
f.instruction(&Instruction::LocalGet(l_z));
f.instruction(&Instruction::I64Const(146_097));
f.instruction(&Instruction::I64DivS);
f.instruction(&Instruction::LocalSet(l_era));
f.instruction(&Instruction::LocalGet(l_z));
f.instruction(&Instruction::LocalGet(l_era));
f.instruction(&Instruction::I64Const(146_097));
f.instruction(&Instruction::I64Mul);
f.instruction(&Instruction::I64Sub);
f.instruction(&Instruction::LocalSet(l_doe));
f.instruction(&Instruction::LocalGet(l_doe));
f.instruction(&Instruction::LocalGet(l_doe));
f.instruction(&Instruction::I64Const(1_460));
f.instruction(&Instruction::I64DivS);
f.instruction(&Instruction::I64Sub);
f.instruction(&Instruction::LocalGet(l_doe));
f.instruction(&Instruction::I64Const(36_524));
f.instruction(&Instruction::I64DivS);
f.instruction(&Instruction::I64Add);
f.instruction(&Instruction::LocalGet(l_doe));
f.instruction(&Instruction::I64Const(146_096));
f.instruction(&Instruction::I64DivS);
f.instruction(&Instruction::I64Sub);
f.instruction(&Instruction::I64Const(365));
f.instruction(&Instruction::I64DivS);
f.instruction(&Instruction::LocalSet(l_yoe));
f.instruction(&Instruction::LocalGet(l_yoe));
f.instruction(&Instruction::LocalGet(l_era));
f.instruction(&Instruction::I64Const(400));
f.instruction(&Instruction::I64Mul);
f.instruction(&Instruction::I64Add);
f.instruction(&Instruction::LocalSet(l_y));
f.instruction(&Instruction::LocalGet(l_doe));
f.instruction(&Instruction::LocalGet(l_yoe));
f.instruction(&Instruction::I64Const(365));
f.instruction(&Instruction::I64Mul);
f.instruction(&Instruction::LocalGet(l_yoe));
f.instruction(&Instruction::I64Const(4));
f.instruction(&Instruction::I64DivS);
f.instruction(&Instruction::I64Add);
f.instruction(&Instruction::LocalGet(l_yoe));
f.instruction(&Instruction::I64Const(100));
f.instruction(&Instruction::I64DivS);
f.instruction(&Instruction::I64Sub);
f.instruction(&Instruction::I64Sub);
f.instruction(&Instruction::LocalSet(l_doy));
f.instruction(&Instruction::LocalGet(l_doy));
f.instruction(&Instruction::I64Const(5));
f.instruction(&Instruction::I64Mul);
f.instruction(&Instruction::I64Const(2));
f.instruction(&Instruction::I64Add);
f.instruction(&Instruction::I64Const(153));
f.instruction(&Instruction::I64DivS);
f.instruction(&Instruction::LocalSet(l_mp_i64));
f.instruction(&Instruction::LocalGet(l_mp_i64));
f.instruction(&Instruction::I32WrapI64);
f.instruction(&Instruction::LocalSet(l_mp));
f.instruction(&Instruction::LocalGet(l_doy));
f.instruction(&Instruction::I32WrapI64);
f.instruction(&Instruction::LocalGet(l_mp));
f.instruction(&Instruction::I32Const(153));
f.instruction(&Instruction::I32Mul);
f.instruction(&Instruction::I32Const(2));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::I32Const(5));
f.instruction(&Instruction::I32DivS);
f.instruction(&Instruction::I32Sub);
f.instruction(&Instruction::I32Const(1));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::LocalSet(l_day));
f.instruction(&Instruction::LocalGet(l_mp));
f.instruction(&Instruction::I32Const(3));
f.instruction(&Instruction::I32Const(-9));
f.instruction(&Instruction::LocalGet(l_mp));
f.instruction(&Instruction::I32Const(10));
f.instruction(&Instruction::I32LtS);
f.instruction(&Instruction::Select);
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::LocalSet(l_month));
f.instruction(&Instruction::LocalGet(l_y));
f.instruction(&Instruction::I32WrapI64);
f.instruction(&Instruction::I32Const(1));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::LocalGet(l_month));
f.instruction(&Instruction::I32Const(2));
f.instruction(&Instruction::I32LeS);
f.instruction(&Instruction::Select);
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::LocalSet(l_year));
f.instruction(&Instruction::I32Const(24));
f.instruction(&Instruction::ArrayNewDefault(string_type_idx));
f.instruction(&Instruction::LocalSet(l_arr));
write_digit(&mut f, l_arr, 0, l_year, 1_000, string_type_idx);
write_digit(&mut f, l_arr, 1, l_year, 100, string_type_idx);
write_digit(&mut f, l_arr, 2, l_year, 10, string_type_idx);
write_digit(&mut f, l_arr, 3, l_year, 1, string_type_idx);
write_byte(&mut f, l_arr, 4, b'-', string_type_idx);
write_digit(&mut f, l_arr, 5, l_month, 10, string_type_idx);
write_digit(&mut f, l_arr, 6, l_month, 1, string_type_idx);
write_byte(&mut f, l_arr, 7, b'-', string_type_idx);
write_digit(&mut f, l_arr, 8, l_day, 10, string_type_idx);
write_digit(&mut f, l_arr, 9, l_day, 1, string_type_idx);
write_byte(&mut f, l_arr, 10, b'T', string_type_idx);
write_digit(&mut f, l_arr, 11, l_hour, 10, string_type_idx);
write_digit(&mut f, l_arr, 12, l_hour, 1, string_type_idx);
write_byte(&mut f, l_arr, 13, b':', string_type_idx);
write_digit(&mut f, l_arr, 14, l_minute, 10, string_type_idx);
write_digit(&mut f, l_arr, 15, l_minute, 1, string_type_idx);
write_byte(&mut f, l_arr, 16, b':', string_type_idx);
write_digit(&mut f, l_arr, 17, l_second, 10, string_type_idx);
write_digit(&mut f, l_arr, 18, l_second, 1, string_type_idx);
write_byte(&mut f, l_arr, 19, b'.', string_type_idx);
write_digit(&mut f, l_arr, 20, l_ms, 100, string_type_idx);
write_digit(&mut f, l_arr, 21, l_ms, 10, string_type_idx);
write_digit(&mut f, l_arr, 22, l_ms, 1, string_type_idx);
write_byte(&mut f, l_arr, 23, b'Z', string_type_idx);
f.instruction(&Instruction::LocalGet(l_arr));
f.instruction(&Instruction::End); f
}
pub(super) fn write_digit(
f: &mut wasm_encoder::Function,
l_arr: u32,
pos: i32,
val_local: u32,
divisor: i32,
string_type_idx: u32,
) {
use wasm_encoder::Instruction;
f.instruction(&Instruction::LocalGet(l_arr));
f.instruction(&Instruction::I32Const(pos));
f.instruction(&Instruction::LocalGet(val_local));
if divisor > 1 {
f.instruction(&Instruction::I32Const(divisor));
f.instruction(&Instruction::I32DivU);
}
f.instruction(&Instruction::I32Const(10));
f.instruction(&Instruction::I32RemU);
f.instruction(&Instruction::I32Const(b'0' as i32));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::ArraySet(string_type_idx));
}
pub(super) fn write_byte(
f: &mut wasm_encoder::Function,
l_arr: u32,
pos: i32,
byte: u8,
string_type_idx: u32,
) {
use wasm_encoder::Instruction;
f.instruction(&Instruction::LocalGet(l_arr));
f.instruction(&Instruction::I32Const(pos));
f.instruction(&Instruction::I32Const(byte as i32));
f.instruction(&Instruction::ArraySet(string_type_idx));
}
pub(super) fn emit_console_read_line(
string_type_idx: u32,
result_type_idx: u32,
stdin_handle_global: u32,
cabi_realloc_fn: u32,
get_stdin_fn: u32,
blocking_read_fn: u32,
) -> wasm_encoder::Function {
use wasm_encoder::{BlockType, Function, HeapType, Instruction, MemArg, RefType};
let s_ref = ValType::Ref(RefType {
nullable: true,
heap_type: HeapType::Concrete(string_type_idx),
});
let _r_ref = ValType::Ref(RefType {
nullable: true,
heap_type: HeapType::Concrete(result_type_idx),
});
let mut f = Function::new(vec![
(11, ValType::I32), (1, s_ref), ]);
let l_stdin_handle = 0u32;
let l_buf_ptr = 1u32;
let l_buf_cap = 2u32;
let l_buf_len = 3u32;
let l_retptr = 4u32;
let l_byte = 5u32;
let l_j = 6u32;
let l_data_ptr = 7u32;
let l_data_len = 8u32;
let l_should_err = 9u32;
let l_new_cap = 10u32;
let l_arr = 11u32;
let _mem4 = MemArg {
offset: 0,
align: 2,
memory_index: 0,
};
let mem4_o4 = MemArg {
offset: 4,
align: 2,
memory_index: 0,
};
let mem4_o8 = MemArg {
offset: 8,
align: 2,
memory_index: 0,
};
let mem1 = MemArg {
offset: 0,
align: 0,
memory_index: 0,
};
f.instruction(&Instruction::GlobalGet(stdin_handle_global));
f.instruction(&Instruction::LocalSet(l_stdin_handle));
f.instruction(&Instruction::LocalGet(l_stdin_handle));
f.instruction(&Instruction::I32Const(-1));
f.instruction(&Instruction::I32Eq);
f.instruction(&Instruction::If(BlockType::Empty));
{
f.instruction(&Instruction::Call(get_stdin_fn));
f.instruction(&Instruction::LocalTee(l_stdin_handle));
f.instruction(&Instruction::GlobalSet(stdin_handle_global));
}
f.instruction(&Instruction::End);
f.instruction(&Instruction::I32Const(0)); f.instruction(&Instruction::I32Const(0)); f.instruction(&Instruction::I32Const(1)); f.instruction(&Instruction::I32Const(256)); f.instruction(&Instruction::Call(cabi_realloc_fn));
f.instruction(&Instruction::LocalSet(l_buf_ptr));
f.instruction(&Instruction::I32Const(256));
f.instruction(&Instruction::LocalSet(l_buf_cap));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::LocalSet(l_buf_len));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::I32Const(4));
f.instruction(&Instruction::I32Const(12));
f.instruction(&Instruction::Call(cabi_realloc_fn));
f.instruction(&Instruction::LocalSet(l_retptr));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::LocalSet(l_should_err));
f.instruction(&Instruction::Block(BlockType::Empty));
f.instruction(&Instruction::Loop(BlockType::Empty));
f.instruction(&Instruction::LocalGet(l_stdin_handle));
f.instruction(&Instruction::I64Const(1));
f.instruction(&Instruction::LocalGet(l_retptr));
f.instruction(&Instruction::Call(blocking_read_fn));
f.instruction(&Instruction::LocalGet(l_retptr));
f.instruction(&Instruction::I32Load8U(mem1));
f.instruction(&Instruction::I32Const(1));
f.instruction(&Instruction::I32Eq);
f.instruction(&Instruction::If(BlockType::Empty));
{
f.instruction(&Instruction::LocalGet(l_buf_len));
f.instruction(&Instruction::I32Eqz);
f.instruction(&Instruction::If(BlockType::Empty));
{
f.instruction(&Instruction::I32Const(1));
f.instruction(&Instruction::LocalSet(l_should_err));
}
f.instruction(&Instruction::End);
f.instruction(&Instruction::Br(2)); }
f.instruction(&Instruction::End);
f.instruction(&Instruction::LocalGet(l_retptr));
f.instruction(&Instruction::I32Load(mem4_o4));
f.instruction(&Instruction::LocalSet(l_data_ptr));
f.instruction(&Instruction::LocalGet(l_retptr));
f.instruction(&Instruction::I32Load(mem4_o8));
f.instruction(&Instruction::LocalSet(l_data_len));
f.instruction(&Instruction::LocalGet(l_data_len));
f.instruction(&Instruction::I32Eqz);
f.instruction(&Instruction::If(BlockType::Empty));
{
f.instruction(&Instruction::LocalGet(l_buf_len));
f.instruction(&Instruction::I32Eqz);
f.instruction(&Instruction::If(BlockType::Empty));
{
f.instruction(&Instruction::I32Const(1));
f.instruction(&Instruction::LocalSet(l_should_err));
}
f.instruction(&Instruction::End);
f.instruction(&Instruction::Br(2)); }
f.instruction(&Instruction::End);
f.instruction(&Instruction::LocalGet(l_data_ptr));
f.instruction(&Instruction::I32Load8U(mem1));
f.instruction(&Instruction::LocalSet(l_byte));
f.instruction(&Instruction::LocalGet(l_byte));
f.instruction(&Instruction::I32Const(10));
f.instruction(&Instruction::I32Eq);
f.instruction(&Instruction::If(BlockType::Empty));
{
f.instruction(&Instruction::Br(2));
}
f.instruction(&Instruction::End);
f.instruction(&Instruction::LocalGet(l_byte));
f.instruction(&Instruction::I32Const(13));
f.instruction(&Instruction::I32Eq);
f.instruction(&Instruction::If(BlockType::Empty));
{
f.instruction(&Instruction::Br(1)); }
f.instruction(&Instruction::End);
f.instruction(&Instruction::LocalGet(l_buf_len));
f.instruction(&Instruction::LocalGet(l_buf_cap));
f.instruction(&Instruction::I32GeU);
f.instruction(&Instruction::If(BlockType::Empty));
{
f.instruction(&Instruction::LocalGet(l_buf_cap));
f.instruction(&Instruction::I32Const(1));
f.instruction(&Instruction::I32Shl);
f.instruction(&Instruction::LocalSet(l_new_cap));
f.instruction(&Instruction::LocalGet(l_buf_ptr));
f.instruction(&Instruction::LocalGet(l_buf_cap));
f.instruction(&Instruction::I32Const(1));
f.instruction(&Instruction::LocalGet(l_new_cap));
f.instruction(&Instruction::Call(cabi_realloc_fn));
f.instruction(&Instruction::LocalSet(l_buf_ptr));
f.instruction(&Instruction::LocalGet(l_new_cap));
f.instruction(&Instruction::LocalSet(l_buf_cap));
}
f.instruction(&Instruction::End);
f.instruction(&Instruction::LocalGet(l_buf_ptr));
f.instruction(&Instruction::LocalGet(l_buf_len));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::LocalGet(l_byte));
f.instruction(&Instruction::I32Store8(mem1));
f.instruction(&Instruction::LocalGet(l_buf_len));
f.instruction(&Instruction::I32Const(1));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::LocalSet(l_buf_len));
f.instruction(&Instruction::Br(0));
f.instruction(&Instruction::End); f.instruction(&Instruction::End);
f.instruction(&Instruction::LocalGet(l_should_err));
f.instruction(&Instruction::If(BlockType::Empty));
{
f.instruction(&Instruction::I32Const(3));
f.instruction(&Instruction::ArrayNewDefault(string_type_idx));
f.instruction(&Instruction::LocalSet(l_arr));
write_byte(&mut f, l_arr, 0, b'E', string_type_idx);
write_byte(&mut f, l_arr, 1, b'O', string_type_idx);
write_byte(&mut f, l_arr, 2, b'F', string_type_idx);
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::RefNull(HeapType::Concrete(string_type_idx)));
f.instruction(&Instruction::LocalGet(l_arr));
f.instruction(&Instruction::StructNew(result_type_idx));
f.instruction(&Instruction::Return);
}
f.instruction(&Instruction::End);
f.instruction(&Instruction::LocalGet(l_buf_len));
f.instruction(&Instruction::ArrayNewDefault(string_type_idx));
f.instruction(&Instruction::LocalSet(l_arr));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::LocalSet(l_j));
f.instruction(&Instruction::Block(BlockType::Empty));
f.instruction(&Instruction::Loop(BlockType::Empty));
f.instruction(&Instruction::LocalGet(l_j));
f.instruction(&Instruction::LocalGet(l_buf_len));
f.instruction(&Instruction::I32GeU);
f.instruction(&Instruction::BrIf(1));
f.instruction(&Instruction::LocalGet(l_arr));
f.instruction(&Instruction::LocalGet(l_j));
f.instruction(&Instruction::LocalGet(l_buf_ptr));
f.instruction(&Instruction::LocalGet(l_j));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::I32Load8U(mem1));
f.instruction(&Instruction::ArraySet(string_type_idx));
f.instruction(&Instruction::LocalGet(l_j));
f.instruction(&Instruction::I32Const(1));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::LocalSet(l_j));
f.instruction(&Instruction::Br(0));
f.instruction(&Instruction::End); f.instruction(&Instruction::End);
f.instruction(&Instruction::I32Const(1));
f.instruction(&Instruction::LocalGet(l_arr));
f.instruction(&Instruction::RefNull(HeapType::Concrete(string_type_idx)));
f.instruction(&Instruction::StructNew(result_type_idx));
f.instruction(&Instruction::End); f
}
pub(super) fn emit_time_sleep(
cabi_realloc_fn: u32,
subscribe_duration_fn: u32,
poll_fn: u32,
drop_pollable_fn: u32,
) -> wasm_encoder::Function {
use wasm_encoder::{Function, Instruction, MemArg};
let mut f = Function::new(vec![(3, ValType::I32)]);
let p_ms = 0u32;
let l_pollable = 1u32;
let l_in_buf = 2u32;
let l_retptr = 3u32;
let mem4 = MemArg {
offset: 0,
align: 2,
memory_index: 0,
};
f.instruction(&Instruction::LocalGet(p_ms));
f.instruction(&Instruction::I64Const(0));
f.instruction(&Instruction::I64LtS);
f.instruction(&Instruction::If(wasm_encoder::BlockType::Empty));
f.instruction(&Instruction::Unreachable);
f.instruction(&Instruction::End);
f.instruction(&Instruction::LocalGet(p_ms));
f.instruction(&Instruction::I64Const(1_000_000));
f.instruction(&Instruction::I64Mul);
f.instruction(&Instruction::Call(subscribe_duration_fn));
f.instruction(&Instruction::LocalSet(l_pollable));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::I32Const(4));
f.instruction(&Instruction::I32Const(4));
f.instruction(&Instruction::Call(cabi_realloc_fn));
f.instruction(&Instruction::LocalSet(l_in_buf));
f.instruction(&Instruction::LocalGet(l_in_buf));
f.instruction(&Instruction::LocalGet(l_pollable));
f.instruction(&Instruction::I32Store(mem4));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::I32Const(4));
f.instruction(&Instruction::I32Const(8));
f.instruction(&Instruction::Call(cabi_realloc_fn));
f.instruction(&Instruction::LocalSet(l_retptr));
f.instruction(&Instruction::LocalGet(l_in_buf));
f.instruction(&Instruction::I32Const(1));
f.instruction(&Instruction::LocalGet(l_retptr));
f.instruction(&Instruction::Call(poll_fn));
f.instruction(&Instruction::LocalGet(l_pollable));
f.instruction(&Instruction::Call(drop_pollable_fn));
f.instruction(&Instruction::End);
f
}
pub(super) fn emit_disk_exists(
preopen_global: u32,
cabi_realloc_fn: u32,
str_to_lm_fn: u32,
get_directories_fn: u32,
stat_at_fn: u32,
) -> wasm_encoder::Function {
use wasm_encoder::{BlockType, Function, Instruction, MemArg};
let mut f = Function::new(vec![(5, ValType::I32)]);
let p_path = 0u32;
let l_preopen = 1u32;
let l_path_len = 2u32;
let l_retptr = 3u32;
let l_list_ptr = 4u32;
let l_list_len = 5u32;
let mem4 = MemArg {
offset: 0,
align: 2,
memory_index: 0,
};
let mem4_o4 = MemArg {
offset: 4,
align: 2,
memory_index: 0,
};
let mem1 = MemArg {
offset: 0,
align: 0,
memory_index: 0,
};
f.instruction(&Instruction::GlobalGet(preopen_global));
f.instruction(&Instruction::LocalSet(l_preopen));
f.instruction(&Instruction::LocalGet(l_preopen));
f.instruction(&Instruction::I32Const(-1));
f.instruction(&Instruction::I32Eq);
f.instruction(&Instruction::If(BlockType::Empty));
{
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::I32Const(4));
f.instruction(&Instruction::I32Const(8));
f.instruction(&Instruction::Call(cabi_realloc_fn));
f.instruction(&Instruction::LocalSet(l_retptr));
f.instruction(&Instruction::LocalGet(l_retptr));
f.instruction(&Instruction::Call(get_directories_fn));
f.instruction(&Instruction::LocalGet(l_retptr));
f.instruction(&Instruction::I32Load(mem4));
f.instruction(&Instruction::LocalSet(l_list_ptr));
f.instruction(&Instruction::LocalGet(l_retptr));
f.instruction(&Instruction::I32Load(mem4_o4));
f.instruction(&Instruction::LocalSet(l_list_len));
f.instruction(&Instruction::LocalGet(l_list_len));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::I32GtU);
f.instruction(&Instruction::If(BlockType::Empty));
{
f.instruction(&Instruction::LocalGet(l_list_ptr));
f.instruction(&Instruction::I32Load(mem4));
f.instruction(&Instruction::LocalTee(l_preopen));
f.instruction(&Instruction::GlobalSet(preopen_global));
}
f.instruction(&Instruction::End);
}
f.instruction(&Instruction::End);
f.instruction(&Instruction::LocalGet(l_preopen));
f.instruction(&Instruction::I32Const(-1));
f.instruction(&Instruction::I32Eq);
f.instruction(&Instruction::If(BlockType::Empty));
{
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::Return);
}
f.instruction(&Instruction::End);
f.instruction(&Instruction::LocalGet(p_path));
f.instruction(&Instruction::Call(str_to_lm_fn));
f.instruction(&Instruction::LocalSet(l_path_len));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::I32Const(8));
f.instruction(&Instruction::I32Const(96));
f.instruction(&Instruction::Call(cabi_realloc_fn));
f.instruction(&Instruction::LocalSet(l_retptr));
f.instruction(&Instruction::LocalGet(l_preopen));
f.instruction(&Instruction::I32Const(1)); f.instruction(&Instruction::I32Const(0)); f.instruction(&Instruction::LocalGet(l_path_len));
f.instruction(&Instruction::LocalGet(l_retptr));
f.instruction(&Instruction::Call(stat_at_fn));
f.instruction(&Instruction::LocalGet(l_retptr));
f.instruction(&Instruction::I32Load8U(mem1));
f.instruction(&Instruction::I32Eqz);
f.instruction(&Instruction::End); f
}
#[allow(clippy::too_many_arguments)]
pub(super) fn emit_disk_read_text(
string_type_idx: u32,
result_type_idx: u32,
preopen_global: u32,
cabi_realloc_fn: u32,
str_to_lm_fn: u32,
get_directories_fn: u32,
open_at_fn: u32,
read_via_stream_fn: u32,
blocking_read_fn: u32,
drop_descriptor_fn: u32,
drop_input_stream_fn: u32,
) -> wasm_encoder::Function {
use wasm_encoder::{BlockType, Function, HeapType, Instruction, MemArg, RefType};
let s_ref = ValType::Ref(RefType {
nullable: true,
heap_type: HeapType::Concrete(string_type_idx),
});
let mut f = Function::new(vec![(16, ValType::I32), (1, s_ref)]);
let p_path = 0u32;
let l_preopen = 1u32;
let l_path_len = 2u32;
let l_retptr_open = 3u32;
let l_retptr_stream = 4u32;
let l_retptr_read = 5u32;
let l_fd = 6u32;
let l_stream = 7u32;
let l_buf_ptr = 8u32;
let l_buf_cap = 9u32;
let l_buf_len = 10u32;
let l_data_ptr = 11u32;
let l_data_len = 12u32;
let l_j = 13u32;
let l_list_ptr = 14u32;
let l_list_len = 15u32;
let l_new_cap = 16u32;
let l_arr = 17u32;
let mem4 = MemArg {
offset: 0,
align: 2,
memory_index: 0,
};
let mem4_o4 = MemArg {
offset: 4,
align: 2,
memory_index: 0,
};
let mem4_o8 = MemArg {
offset: 8,
align: 2,
memory_index: 0,
};
let mem1 = MemArg {
offset: 0,
align: 0,
memory_index: 0,
};
let emit_err = |f: &mut Function, msg: &[u8]| {
f.instruction(&Instruction::I32Const(msg.len() as i32));
f.instruction(&Instruction::ArrayNewDefault(string_type_idx));
f.instruction(&Instruction::LocalSet(l_arr));
for (i, b) in msg.iter().enumerate() {
f.instruction(&Instruction::LocalGet(l_arr));
f.instruction(&Instruction::I32Const(i as i32));
f.instruction(&Instruction::I32Const(*b as i32));
f.instruction(&Instruction::ArraySet(string_type_idx));
}
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::RefNull(HeapType::Concrete(string_type_idx)));
f.instruction(&Instruction::LocalGet(l_arr));
f.instruction(&Instruction::StructNew(result_type_idx));
f.instruction(&Instruction::Return);
};
f.instruction(&Instruction::GlobalGet(preopen_global));
f.instruction(&Instruction::LocalSet(l_preopen));
f.instruction(&Instruction::LocalGet(l_preopen));
f.instruction(&Instruction::I32Const(-1));
f.instruction(&Instruction::I32Eq);
f.instruction(&Instruction::If(BlockType::Empty));
{
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::I32Const(4));
f.instruction(&Instruction::I32Const(8));
f.instruction(&Instruction::Call(cabi_realloc_fn));
f.instruction(&Instruction::LocalSet(l_retptr_open));
f.instruction(&Instruction::LocalGet(l_retptr_open));
f.instruction(&Instruction::Call(get_directories_fn));
f.instruction(&Instruction::LocalGet(l_retptr_open));
f.instruction(&Instruction::I32Load(mem4));
f.instruction(&Instruction::LocalSet(l_list_ptr));
f.instruction(&Instruction::LocalGet(l_retptr_open));
f.instruction(&Instruction::I32Load(mem4_o4));
f.instruction(&Instruction::LocalSet(l_list_len));
f.instruction(&Instruction::LocalGet(l_list_len));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::I32GtU);
f.instruction(&Instruction::If(BlockType::Empty));
{
f.instruction(&Instruction::LocalGet(l_list_ptr));
f.instruction(&Instruction::I32Load(mem4));
f.instruction(&Instruction::LocalTee(l_preopen));
f.instruction(&Instruction::GlobalSet(preopen_global));
}
f.instruction(&Instruction::End);
}
f.instruction(&Instruction::End);
f.instruction(&Instruction::LocalGet(l_preopen));
f.instruction(&Instruction::I32Const(-1));
f.instruction(&Instruction::I32Eq);
f.instruction(&Instruction::If(BlockType::Empty));
{
emit_err(&mut f, b"no preopens");
}
f.instruction(&Instruction::End);
f.instruction(&Instruction::LocalGet(p_path));
f.instruction(&Instruction::Call(str_to_lm_fn));
f.instruction(&Instruction::LocalSet(l_path_len));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::I32Const(4));
f.instruction(&Instruction::I32Const(8));
f.instruction(&Instruction::Call(cabi_realloc_fn));
f.instruction(&Instruction::LocalSet(l_retptr_open));
f.instruction(&Instruction::LocalGet(l_preopen));
f.instruction(&Instruction::I32Const(1)); f.instruction(&Instruction::I32Const(0)); f.instruction(&Instruction::LocalGet(l_path_len));
f.instruction(&Instruction::I32Const(0)); f.instruction(&Instruction::I32Const(1)); f.instruction(&Instruction::LocalGet(l_retptr_open));
f.instruction(&Instruction::Call(open_at_fn));
f.instruction(&Instruction::LocalGet(l_retptr_open));
f.instruction(&Instruction::I32Load8U(mem1));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::I32Ne);
f.instruction(&Instruction::If(BlockType::Empty));
{
emit_err(&mut f, b"open failed");
}
f.instruction(&Instruction::End);
f.instruction(&Instruction::LocalGet(l_retptr_open));
f.instruction(&Instruction::I32Load(mem4_o4));
f.instruction(&Instruction::LocalSet(l_fd));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::I32Const(4));
f.instruction(&Instruction::I32Const(8));
f.instruction(&Instruction::Call(cabi_realloc_fn));
f.instruction(&Instruction::LocalSet(l_retptr_stream));
f.instruction(&Instruction::LocalGet(l_fd));
f.instruction(&Instruction::I64Const(0));
f.instruction(&Instruction::LocalGet(l_retptr_stream));
f.instruction(&Instruction::Call(read_via_stream_fn));
f.instruction(&Instruction::LocalGet(l_retptr_stream));
f.instruction(&Instruction::I32Load8U(mem1));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::I32Ne);
f.instruction(&Instruction::If(BlockType::Empty));
{
f.instruction(&Instruction::LocalGet(l_fd));
f.instruction(&Instruction::Call(drop_descriptor_fn));
emit_err(&mut f, b"read-via-stream failed");
}
f.instruction(&Instruction::End);
f.instruction(&Instruction::LocalGet(l_retptr_stream));
f.instruction(&Instruction::I32Load(mem4_o4));
f.instruction(&Instruction::LocalSet(l_stream));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::I32Const(1));
f.instruction(&Instruction::I32Const(4096));
f.instruction(&Instruction::Call(cabi_realloc_fn));
f.instruction(&Instruction::LocalSet(l_buf_ptr));
f.instruction(&Instruction::I32Const(4096));
f.instruction(&Instruction::LocalSet(l_buf_cap));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::LocalSet(l_buf_len));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::I32Const(4));
f.instruction(&Instruction::I32Const(12));
f.instruction(&Instruction::Call(cabi_realloc_fn));
f.instruction(&Instruction::LocalSet(l_retptr_read));
f.instruction(&Instruction::Block(BlockType::Empty));
f.instruction(&Instruction::Loop(BlockType::Empty));
f.instruction(&Instruction::LocalGet(l_stream));
f.instruction(&Instruction::I64Const(65_536));
f.instruction(&Instruction::LocalGet(l_retptr_read));
f.instruction(&Instruction::Call(blocking_read_fn));
f.instruction(&Instruction::LocalGet(l_retptr_read));
f.instruction(&Instruction::I32Load8U(mem1));
f.instruction(&Instruction::I32Const(1));
f.instruction(&Instruction::I32Eq);
f.instruction(&Instruction::If(BlockType::Empty));
{
f.instruction(&Instruction::LocalGet(l_retptr_read));
f.instruction(&Instruction::I32Load8U(MemArg {
offset: 4,
align: 0,
memory_index: 0,
}));
f.instruction(&Instruction::I32Const(1));
f.instruction(&Instruction::I32Eq);
f.instruction(&Instruction::If(BlockType::Empty));
{
f.instruction(&Instruction::Br(3));
}
f.instruction(&Instruction::End);
f.instruction(&Instruction::LocalGet(l_stream));
f.instruction(&Instruction::Call(drop_input_stream_fn));
f.instruction(&Instruction::LocalGet(l_fd));
f.instruction(&Instruction::Call(drop_descriptor_fn));
emit_err(&mut f, b"read failed");
}
f.instruction(&Instruction::End);
f.instruction(&Instruction::LocalGet(l_retptr_read));
f.instruction(&Instruction::I32Load(mem4_o4));
f.instruction(&Instruction::LocalSet(l_data_ptr));
f.instruction(&Instruction::LocalGet(l_retptr_read));
f.instruction(&Instruction::I32Load(mem4_o8));
f.instruction(&Instruction::LocalSet(l_data_len));
f.instruction(&Instruction::LocalGet(l_data_len));
f.instruction(&Instruction::I32Eqz);
f.instruction(&Instruction::BrIf(1));
f.instruction(&Instruction::LocalGet(l_buf_cap));
f.instruction(&Instruction::LocalSet(l_new_cap));
f.instruction(&Instruction::Block(BlockType::Empty));
f.instruction(&Instruction::Loop(BlockType::Empty));
f.instruction(&Instruction::LocalGet(l_new_cap));
f.instruction(&Instruction::LocalGet(l_buf_len));
f.instruction(&Instruction::LocalGet(l_data_len));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::I32GeU);
f.instruction(&Instruction::BrIf(1));
f.instruction(&Instruction::LocalGet(l_new_cap));
f.instruction(&Instruction::I32Const(1));
f.instruction(&Instruction::I32Shl);
f.instruction(&Instruction::LocalSet(l_new_cap));
f.instruction(&Instruction::Br(0));
f.instruction(&Instruction::End); f.instruction(&Instruction::End); f.instruction(&Instruction::LocalGet(l_new_cap));
f.instruction(&Instruction::LocalGet(l_buf_cap));
f.instruction(&Instruction::I32GtU);
f.instruction(&Instruction::If(BlockType::Empty));
{
f.instruction(&Instruction::LocalGet(l_buf_ptr));
f.instruction(&Instruction::LocalGet(l_buf_cap));
f.instruction(&Instruction::I32Const(1));
f.instruction(&Instruction::LocalGet(l_new_cap));
f.instruction(&Instruction::Call(cabi_realloc_fn));
f.instruction(&Instruction::LocalSet(l_buf_ptr));
f.instruction(&Instruction::LocalGet(l_new_cap));
f.instruction(&Instruction::LocalSet(l_buf_cap));
}
f.instruction(&Instruction::End);
f.instruction(&Instruction::LocalGet(l_buf_ptr));
f.instruction(&Instruction::LocalGet(l_buf_len));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::LocalGet(l_data_ptr));
f.instruction(&Instruction::LocalGet(l_data_len));
f.instruction(&Instruction::MemoryCopy {
src_mem: 0,
dst_mem: 0,
});
f.instruction(&Instruction::LocalGet(l_buf_len));
f.instruction(&Instruction::LocalGet(l_data_len));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::LocalSet(l_buf_len));
f.instruction(&Instruction::Br(0));
f.instruction(&Instruction::End); f.instruction(&Instruction::End);
f.instruction(&Instruction::LocalGet(l_stream));
f.instruction(&Instruction::Call(drop_input_stream_fn));
f.instruction(&Instruction::LocalGet(l_fd));
f.instruction(&Instruction::Call(drop_descriptor_fn));
f.instruction(&Instruction::LocalGet(l_buf_len));
f.instruction(&Instruction::ArrayNewDefault(string_type_idx));
f.instruction(&Instruction::LocalSet(l_arr));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::LocalSet(l_j));
f.instruction(&Instruction::Block(BlockType::Empty));
f.instruction(&Instruction::Loop(BlockType::Empty));
f.instruction(&Instruction::LocalGet(l_j));
f.instruction(&Instruction::LocalGet(l_buf_len));
f.instruction(&Instruction::I32GeU);
f.instruction(&Instruction::BrIf(1));
f.instruction(&Instruction::LocalGet(l_arr));
f.instruction(&Instruction::LocalGet(l_j));
f.instruction(&Instruction::LocalGet(l_buf_ptr));
f.instruction(&Instruction::LocalGet(l_j));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::I32Load8U(mem1));
f.instruction(&Instruction::ArraySet(string_type_idx));
f.instruction(&Instruction::LocalGet(l_j));
f.instruction(&Instruction::I32Const(1));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::LocalSet(l_j));
f.instruction(&Instruction::Br(0));
f.instruction(&Instruction::End); f.instruction(&Instruction::End);
f.instruction(&Instruction::I32Const(1));
f.instruction(&Instruction::LocalGet(l_arr));
f.instruction(&Instruction::RefNull(HeapType::Concrete(string_type_idx)));
f.instruction(&Instruction::StructNew(result_type_idx));
f.instruction(&Instruction::End); f
}
#[allow(clippy::too_many_arguments)]
pub(super) fn emit_disk_write_text(
string_type_idx: u32,
result_type_idx: u32,
preopen_global: u32,
cabi_realloc_fn: u32,
str_to_lm_fn: u32,
get_directories_fn: u32,
open_at_fn: u32,
write_via_stream_fn: u32,
blocking_write_fn: u32,
drop_descriptor_fn: u32,
drop_output_stream_fn: u32,
is_append: bool,
) -> wasm_encoder::Function {
use wasm_encoder::{BlockType, Function, HeapType, Instruction, MemArg, RefType};
let s_ref = ValType::Ref(RefType {
nullable: true,
heap_type: HeapType::Concrete(string_type_idx),
});
let mut f = Function::new(vec![(11, ValType::I32), (1, s_ref)]);
let p_path = 0u32;
let p_content = 1u32;
let l_preopen = 2u32;
let l_path_len = 3u32;
let l_content_len = 4u32;
let l_retptr_open = 5u32;
let l_retptr_stream = 6u32;
let l_retptr_write = 7u32;
let l_fd = 8u32;
let l_stream = 9u32;
let l_list_ptr = 10u32;
let l_list_len = 11u32;
let l_write_off = 12u32;
let l_arr = 13u32;
let mem4 = MemArg {
offset: 0,
align: 2,
memory_index: 0,
};
let mem4_o4 = MemArg {
offset: 4,
align: 2,
memory_index: 0,
};
let mem1 = MemArg {
offset: 0,
align: 0,
memory_index: 0,
};
let emit_err = |f: &mut Function, msg: &[u8]| {
f.instruction(&Instruction::I32Const(msg.len() as i32));
f.instruction(&Instruction::ArrayNewDefault(string_type_idx));
f.instruction(&Instruction::LocalSet(l_arr));
for (i, b) in msg.iter().enumerate() {
f.instruction(&Instruction::LocalGet(l_arr));
f.instruction(&Instruction::I32Const(i as i32));
f.instruction(&Instruction::I32Const(*b as i32));
f.instruction(&Instruction::ArraySet(string_type_idx));
}
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::LocalGet(l_arr));
f.instruction(&Instruction::StructNew(result_type_idx));
f.instruction(&Instruction::Return);
};
f.instruction(&Instruction::GlobalGet(preopen_global));
f.instruction(&Instruction::LocalSet(l_preopen));
f.instruction(&Instruction::LocalGet(l_preopen));
f.instruction(&Instruction::I32Const(-1));
f.instruction(&Instruction::I32Eq);
f.instruction(&Instruction::If(BlockType::Empty));
{
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::I32Const(4));
f.instruction(&Instruction::I32Const(8));
f.instruction(&Instruction::Call(cabi_realloc_fn));
f.instruction(&Instruction::LocalSet(l_retptr_open));
f.instruction(&Instruction::LocalGet(l_retptr_open));
f.instruction(&Instruction::Call(get_directories_fn));
f.instruction(&Instruction::LocalGet(l_retptr_open));
f.instruction(&Instruction::I32Load(mem4));
f.instruction(&Instruction::LocalSet(l_list_ptr));
f.instruction(&Instruction::LocalGet(l_retptr_open));
f.instruction(&Instruction::I32Load(mem4_o4));
f.instruction(&Instruction::LocalSet(l_list_len));
f.instruction(&Instruction::LocalGet(l_list_len));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::I32GtU);
f.instruction(&Instruction::If(BlockType::Empty));
{
f.instruction(&Instruction::LocalGet(l_list_ptr));
f.instruction(&Instruction::I32Load(mem4));
f.instruction(&Instruction::LocalTee(l_preopen));
f.instruction(&Instruction::GlobalSet(preopen_global));
}
f.instruction(&Instruction::End);
}
f.instruction(&Instruction::End);
f.instruction(&Instruction::LocalGet(l_preopen));
f.instruction(&Instruction::I32Const(-1));
f.instruction(&Instruction::I32Eq);
f.instruction(&Instruction::If(BlockType::Empty));
{
emit_err(&mut f, b"no preopens");
}
f.instruction(&Instruction::End);
f.instruction(&Instruction::LocalGet(p_path));
f.instruction(&Instruction::Call(str_to_lm_fn));
f.instruction(&Instruction::LocalSet(l_path_len));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::I32Const(4));
f.instruction(&Instruction::I32Const(8));
f.instruction(&Instruction::Call(cabi_realloc_fn));
f.instruction(&Instruction::LocalSet(l_retptr_open));
f.instruction(&Instruction::LocalGet(l_preopen));
f.instruction(&Instruction::I32Const(1)); f.instruction(&Instruction::I32Const(0)); f.instruction(&Instruction::LocalGet(l_path_len));
f.instruction(&Instruction::I32Const(if is_append { 1 } else { 9 }));
f.instruction(&Instruction::I32Const(2)); f.instruction(&Instruction::LocalGet(l_retptr_open));
f.instruction(&Instruction::Call(open_at_fn));
f.instruction(&Instruction::LocalGet(l_retptr_open));
f.instruction(&Instruction::I32Load8U(mem1));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::I32Ne);
f.instruction(&Instruction::If(BlockType::Empty));
{
emit_err(&mut f, b"open failed");
}
f.instruction(&Instruction::End);
f.instruction(&Instruction::LocalGet(l_retptr_open));
f.instruction(&Instruction::I32Load(mem4_o4));
f.instruction(&Instruction::LocalSet(l_fd));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::I32Const(4));
f.instruction(&Instruction::I32Const(8));
f.instruction(&Instruction::Call(cabi_realloc_fn));
f.instruction(&Instruction::LocalSet(l_retptr_stream));
f.instruction(&Instruction::LocalGet(l_fd));
if !is_append {
f.instruction(&Instruction::I64Const(0));
}
f.instruction(&Instruction::LocalGet(l_retptr_stream));
f.instruction(&Instruction::Call(write_via_stream_fn));
f.instruction(&Instruction::LocalGet(l_retptr_stream));
f.instruction(&Instruction::I32Load8U(mem1));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::I32Ne);
f.instruction(&Instruction::If(BlockType::Empty));
{
f.instruction(&Instruction::LocalGet(l_fd));
f.instruction(&Instruction::Call(drop_descriptor_fn));
emit_err(
&mut f,
if is_append {
b"append-via-stream failed"
} else {
b"write-via-stream failed"
},
);
}
f.instruction(&Instruction::End);
f.instruction(&Instruction::LocalGet(l_retptr_stream));
f.instruction(&Instruction::I32Load(mem4_o4));
f.instruction(&Instruction::LocalSet(l_stream));
f.instruction(&Instruction::LocalGet(p_content));
f.instruction(&Instruction::Call(str_to_lm_fn));
f.instruction(&Instruction::LocalSet(l_content_len));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::I32Const(4));
f.instruction(&Instruction::I32Const(12));
f.instruction(&Instruction::Call(cabi_realloc_fn));
f.instruction(&Instruction::LocalSet(l_retptr_write));
emit_chunked_blocking_write(
&mut f,
l_content_len,
l_write_off,
blocking_write_fn,
&|inner| {
inner.instruction(&Instruction::LocalGet(l_stream));
},
&|inner| {
inner.instruction(&Instruction::LocalGet(l_retptr_write));
},
Some(&|inner| {
inner.instruction(&Instruction::LocalGet(l_stream));
inner.instruction(&Instruction::Call(drop_output_stream_fn));
inner.instruction(&Instruction::LocalGet(l_fd));
inner.instruction(&Instruction::Call(drop_descriptor_fn));
let msg = b"write failed";
inner.instruction(&Instruction::I32Const(msg.len() as i32));
inner.instruction(&Instruction::ArrayNewDefault(string_type_idx));
inner.instruction(&Instruction::LocalSet(l_arr));
for (i, b) in msg.iter().enumerate() {
inner.instruction(&Instruction::LocalGet(l_arr));
inner.instruction(&Instruction::I32Const(i as i32));
inner.instruction(&Instruction::I32Const(*b as i32));
inner.instruction(&Instruction::ArraySet(string_type_idx));
}
inner.instruction(&Instruction::I32Const(0));
inner.instruction(&Instruction::I32Const(0));
inner.instruction(&Instruction::LocalGet(l_arr));
inner.instruction(&Instruction::StructNew(result_type_idx));
inner.instruction(&Instruction::Return);
}),
);
f.instruction(&Instruction::LocalGet(l_stream));
f.instruction(&Instruction::Call(drop_output_stream_fn));
f.instruction(&Instruction::LocalGet(l_fd));
f.instruction(&Instruction::Call(drop_descriptor_fn));
f.instruction(&Instruction::I32Const(1));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::RefNull(HeapType::Concrete(string_type_idx)));
f.instruction(&Instruction::StructNew(result_type_idx));
f.instruction(&Instruction::End); f
}
#[allow(clippy::too_many_arguments)]
pub(super) fn emit_disk_simple_path_op(
string_type_idx: u32,
result_type_idx: u32,
preopen_global: u32,
cabi_realloc_fn: u32,
str_to_lm_fn: u32,
get_directories_fn: u32,
op_fn: u32,
err_msg: &[u8],
) -> wasm_encoder::Function {
use wasm_encoder::{BlockType, Function, HeapType, Instruction, MemArg, RefType};
let s_ref = ValType::Ref(RefType {
nullable: true,
heap_type: HeapType::Concrete(string_type_idx),
});
let mut f = Function::new(vec![(5, ValType::I32), (1, s_ref)]);
let p_path = 0u32;
let l_preopen = 1u32;
let l_path_len = 2u32;
let l_retptr = 3u32;
let l_list_ptr = 4u32;
let l_list_len = 5u32;
let l_arr = 6u32;
let mem4 = MemArg {
offset: 0,
align: 2,
memory_index: 0,
};
let mem4_o4 = MemArg {
offset: 4,
align: 2,
memory_index: 0,
};
let mem1 = MemArg {
offset: 0,
align: 0,
memory_index: 0,
};
let emit_err = |f: &mut Function| {
f.instruction(&Instruction::I32Const(err_msg.len() as i32));
f.instruction(&Instruction::ArrayNewDefault(string_type_idx));
f.instruction(&Instruction::LocalSet(l_arr));
for (i, b) in err_msg.iter().enumerate() {
f.instruction(&Instruction::LocalGet(l_arr));
f.instruction(&Instruction::I32Const(i as i32));
f.instruction(&Instruction::I32Const(*b as i32));
f.instruction(&Instruction::ArraySet(string_type_idx));
}
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::LocalGet(l_arr));
f.instruction(&Instruction::StructNew(result_type_idx));
f.instruction(&Instruction::Return);
};
f.instruction(&Instruction::GlobalGet(preopen_global));
f.instruction(&Instruction::LocalSet(l_preopen));
f.instruction(&Instruction::LocalGet(l_preopen));
f.instruction(&Instruction::I32Const(-1));
f.instruction(&Instruction::I32Eq);
f.instruction(&Instruction::If(BlockType::Empty));
{
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::I32Const(4));
f.instruction(&Instruction::I32Const(8));
f.instruction(&Instruction::Call(cabi_realloc_fn));
f.instruction(&Instruction::LocalSet(l_retptr));
f.instruction(&Instruction::LocalGet(l_retptr));
f.instruction(&Instruction::Call(get_directories_fn));
f.instruction(&Instruction::LocalGet(l_retptr));
f.instruction(&Instruction::I32Load(mem4));
f.instruction(&Instruction::LocalSet(l_list_ptr));
f.instruction(&Instruction::LocalGet(l_retptr));
f.instruction(&Instruction::I32Load(mem4_o4));
f.instruction(&Instruction::LocalSet(l_list_len));
f.instruction(&Instruction::LocalGet(l_list_len));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::I32GtU);
f.instruction(&Instruction::If(BlockType::Empty));
{
f.instruction(&Instruction::LocalGet(l_list_ptr));
f.instruction(&Instruction::I32Load(mem4));
f.instruction(&Instruction::LocalTee(l_preopen));
f.instruction(&Instruction::GlobalSet(preopen_global));
}
f.instruction(&Instruction::End);
}
f.instruction(&Instruction::End);
f.instruction(&Instruction::LocalGet(l_preopen));
f.instruction(&Instruction::I32Const(-1));
f.instruction(&Instruction::I32Eq);
f.instruction(&Instruction::If(BlockType::Empty));
{
emit_err(&mut f);
}
f.instruction(&Instruction::End);
f.instruction(&Instruction::LocalGet(p_path));
f.instruction(&Instruction::Call(str_to_lm_fn));
f.instruction(&Instruction::LocalSet(l_path_len));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::I32Const(4));
f.instruction(&Instruction::I32Const(4));
f.instruction(&Instruction::Call(cabi_realloc_fn));
f.instruction(&Instruction::LocalSet(l_retptr));
f.instruction(&Instruction::LocalGet(l_preopen));
f.instruction(&Instruction::I32Const(0)); f.instruction(&Instruction::LocalGet(l_path_len));
f.instruction(&Instruction::LocalGet(l_retptr));
f.instruction(&Instruction::Call(op_fn));
f.instruction(&Instruction::LocalGet(l_retptr));
f.instruction(&Instruction::I32Load8U(mem1));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::I32Ne);
f.instruction(&Instruction::If(BlockType::Empty));
{
emit_err(&mut f);
}
f.instruction(&Instruction::End);
f.instruction(&Instruction::I32Const(1));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::RefNull(HeapType::Concrete(string_type_idx)));
f.instruction(&Instruction::StructNew(result_type_idx));
f.instruction(&Instruction::End); f
}
#[allow(clippy::too_many_arguments)]
pub(super) fn emit_disk_list_dir(
string_type_idx: u32,
list_string_type_idx: u32,
result_type_idx: u32,
preopen_global: u32,
cabi_realloc_fn: u32,
str_to_lm_fn: u32,
get_directories_fn: u32,
open_at_fn: u32,
read_directory_fn: u32,
read_directory_entry_fn: u32,
drop_descriptor_fn: u32,
drop_dir_entry_stream_fn: u32,
) -> wasm_encoder::Function {
use wasm_encoder::{BlockType, Function, HeapType, Instruction, MemArg, RefType};
let s_ref = ValType::Ref(RefType {
nullable: true,
heap_type: HeapType::Concrete(string_type_idx),
});
let l_ref = ValType::Ref(RefType {
nullable: true,
heap_type: HeapType::Concrete(list_string_type_idx),
});
let mut f = Function::new(vec![(12, ValType::I32), (1, s_ref), (1, l_ref)]);
let p_path = 0u32;
let l_preopen = 1u32;
let l_path_len = 2u32;
let l_retptr_open = 3u32;
let l_retptr_stream = 4u32;
let l_retptr_entry = 5u32;
let l_fd = 6u32;
let l_dstream = 7u32;
let l_name_ptr = 8u32;
let l_name_len = 9u32;
let l_j = 10u32;
let l_list_ptr = 11u32;
let l_list_len = 12u32;
let l_arr = 13u32;
let l_acc = 14u32;
let mem4 = MemArg {
offset: 0,
align: 2,
memory_index: 0,
};
let mem4_o4 = MemArg {
offset: 4,
align: 2,
memory_index: 0,
};
let mem1 = MemArg {
offset: 0,
align: 0,
memory_index: 0,
};
let emit_err = |f: &mut Function, msg: &[u8]| {
f.instruction(&Instruction::I32Const(msg.len() as i32));
f.instruction(&Instruction::ArrayNewDefault(string_type_idx));
f.instruction(&Instruction::LocalSet(l_arr));
for (i, b) in msg.iter().enumerate() {
f.instruction(&Instruction::LocalGet(l_arr));
f.instruction(&Instruction::I32Const(i as i32));
f.instruction(&Instruction::I32Const(*b as i32));
f.instruction(&Instruction::ArraySet(string_type_idx));
}
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::RefNull(HeapType::Concrete(
list_string_type_idx,
)));
f.instruction(&Instruction::LocalGet(l_arr));
f.instruction(&Instruction::StructNew(result_type_idx));
f.instruction(&Instruction::Return);
};
f.instruction(&Instruction::GlobalGet(preopen_global));
f.instruction(&Instruction::LocalSet(l_preopen));
f.instruction(&Instruction::LocalGet(l_preopen));
f.instruction(&Instruction::I32Const(-1));
f.instruction(&Instruction::I32Eq);
f.instruction(&Instruction::If(BlockType::Empty));
{
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::I32Const(4));
f.instruction(&Instruction::I32Const(8));
f.instruction(&Instruction::Call(cabi_realloc_fn));
f.instruction(&Instruction::LocalSet(l_retptr_open));
f.instruction(&Instruction::LocalGet(l_retptr_open));
f.instruction(&Instruction::Call(get_directories_fn));
f.instruction(&Instruction::LocalGet(l_retptr_open));
f.instruction(&Instruction::I32Load(mem4));
f.instruction(&Instruction::LocalSet(l_list_ptr));
f.instruction(&Instruction::LocalGet(l_retptr_open));
f.instruction(&Instruction::I32Load(mem4_o4));
f.instruction(&Instruction::LocalSet(l_list_len));
f.instruction(&Instruction::LocalGet(l_list_len));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::I32GtU);
f.instruction(&Instruction::If(BlockType::Empty));
{
f.instruction(&Instruction::LocalGet(l_list_ptr));
f.instruction(&Instruction::I32Load(mem4));
f.instruction(&Instruction::LocalTee(l_preopen));
f.instruction(&Instruction::GlobalSet(preopen_global));
}
f.instruction(&Instruction::End);
}
f.instruction(&Instruction::End);
f.instruction(&Instruction::LocalGet(l_preopen));
f.instruction(&Instruction::I32Const(-1));
f.instruction(&Instruction::I32Eq);
f.instruction(&Instruction::If(BlockType::Empty));
{
emit_err(&mut f, b"no preopens");
}
f.instruction(&Instruction::End);
f.instruction(&Instruction::LocalGet(p_path));
f.instruction(&Instruction::Call(str_to_lm_fn));
f.instruction(&Instruction::LocalSet(l_path_len));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::I32Const(4));
f.instruction(&Instruction::I32Const(8));
f.instruction(&Instruction::Call(cabi_realloc_fn));
f.instruction(&Instruction::LocalSet(l_retptr_open));
f.instruction(&Instruction::LocalGet(l_preopen));
f.instruction(&Instruction::I32Const(1)); f.instruction(&Instruction::I32Const(0)); f.instruction(&Instruction::LocalGet(l_path_len));
f.instruction(&Instruction::I32Const(2)); f.instruction(&Instruction::I32Const(1)); f.instruction(&Instruction::LocalGet(l_retptr_open));
f.instruction(&Instruction::Call(open_at_fn));
f.instruction(&Instruction::LocalGet(l_retptr_open));
f.instruction(&Instruction::I32Load8U(mem1));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::I32Ne);
f.instruction(&Instruction::If(BlockType::Empty));
{
emit_err(&mut f, b"opendir failed");
}
f.instruction(&Instruction::End);
f.instruction(&Instruction::LocalGet(l_retptr_open));
f.instruction(&Instruction::I32Load(mem4_o4));
f.instruction(&Instruction::LocalSet(l_fd));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::I32Const(4));
f.instruction(&Instruction::I32Const(8));
f.instruction(&Instruction::Call(cabi_realloc_fn));
f.instruction(&Instruction::LocalSet(l_retptr_stream));
f.instruction(&Instruction::LocalGet(l_fd));
f.instruction(&Instruction::LocalGet(l_retptr_stream));
f.instruction(&Instruction::Call(read_directory_fn));
f.instruction(&Instruction::LocalGet(l_retptr_stream));
f.instruction(&Instruction::I32Load8U(mem1));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::I32Ne);
f.instruction(&Instruction::If(BlockType::Empty));
{
f.instruction(&Instruction::LocalGet(l_fd));
f.instruction(&Instruction::Call(drop_descriptor_fn));
emit_err(&mut f, b"read-directory failed");
}
f.instruction(&Instruction::End);
f.instruction(&Instruction::LocalGet(l_retptr_stream));
f.instruction(&Instruction::I32Load(mem4_o4));
f.instruction(&Instruction::LocalSet(l_dstream));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::I32Const(4));
f.instruction(&Instruction::I32Const(20));
f.instruction(&Instruction::Call(cabi_realloc_fn));
f.instruction(&Instruction::LocalSet(l_retptr_entry));
f.instruction(&Instruction::RefNull(HeapType::Concrete(
list_string_type_idx,
)));
f.instruction(&Instruction::LocalSet(l_acc));
f.instruction(&Instruction::Block(BlockType::Empty));
f.instruction(&Instruction::Loop(BlockType::Empty));
f.instruction(&Instruction::LocalGet(l_dstream));
f.instruction(&Instruction::LocalGet(l_retptr_entry));
f.instruction(&Instruction::Call(read_directory_entry_fn));
f.instruction(&Instruction::LocalGet(l_retptr_entry));
f.instruction(&Instruction::I32Load8U(mem1));
f.instruction(&Instruction::I32Const(1));
f.instruction(&Instruction::I32Eq);
f.instruction(&Instruction::If(BlockType::Empty));
{
f.instruction(&Instruction::LocalGet(l_dstream));
f.instruction(&Instruction::Call(drop_dir_entry_stream_fn));
f.instruction(&Instruction::LocalGet(l_fd));
f.instruction(&Instruction::Call(drop_descriptor_fn));
emit_err(&mut f, b"readdir failed");
}
f.instruction(&Instruction::End);
f.instruction(&Instruction::LocalGet(l_retptr_entry));
f.instruction(&Instruction::I32Load8U(MemArg {
offset: 4,
align: 0,
memory_index: 0,
}));
f.instruction(&Instruction::I32Eqz);
f.instruction(&Instruction::BrIf(1));
f.instruction(&Instruction::LocalGet(l_retptr_entry));
f.instruction(&Instruction::I32Load(MemArg {
offset: 12,
align: 2,
memory_index: 0,
}));
f.instruction(&Instruction::LocalSet(l_name_ptr));
f.instruction(&Instruction::LocalGet(l_retptr_entry));
f.instruction(&Instruction::I32Load(MemArg {
offset: 16,
align: 2,
memory_index: 0,
}));
f.instruction(&Instruction::LocalSet(l_name_len));
f.instruction(&Instruction::LocalGet(l_name_len));
f.instruction(&Instruction::ArrayNewDefault(string_type_idx));
f.instruction(&Instruction::LocalSet(l_arr));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::LocalSet(l_j));
f.instruction(&Instruction::Block(BlockType::Empty));
f.instruction(&Instruction::Loop(BlockType::Empty));
f.instruction(&Instruction::LocalGet(l_j));
f.instruction(&Instruction::LocalGet(l_name_len));
f.instruction(&Instruction::I32GeU);
f.instruction(&Instruction::BrIf(1));
f.instruction(&Instruction::LocalGet(l_arr));
f.instruction(&Instruction::LocalGet(l_j));
f.instruction(&Instruction::LocalGet(l_name_ptr));
f.instruction(&Instruction::LocalGet(l_j));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::I32Load8U(mem1));
f.instruction(&Instruction::ArraySet(string_type_idx));
f.instruction(&Instruction::LocalGet(l_j));
f.instruction(&Instruction::I32Const(1));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::LocalSet(l_j));
f.instruction(&Instruction::Br(0));
f.instruction(&Instruction::End); f.instruction(&Instruction::End);
f.instruction(&Instruction::LocalGet(l_arr));
f.instruction(&Instruction::LocalGet(l_acc));
f.instruction(&Instruction::StructNew(list_string_type_idx));
f.instruction(&Instruction::LocalSet(l_acc));
f.instruction(&Instruction::Br(0));
f.instruction(&Instruction::End); f.instruction(&Instruction::End);
f.instruction(&Instruction::LocalGet(l_dstream));
f.instruction(&Instruction::Call(drop_dir_entry_stream_fn));
f.instruction(&Instruction::LocalGet(l_fd));
f.instruction(&Instruction::Call(drop_descriptor_fn));
f.instruction(&Instruction::I32Const(1));
f.instruction(&Instruction::LocalGet(l_acc));
f.instruction(&Instruction::RefNull(HeapType::Concrete(string_type_idx)));
f.instruction(&Instruction::StructNew(result_type_idx));
f.instruction(&Instruction::End); f
}