use wasm_encoder::{Function, Instruction, ValType};
use super::super::value::*;
use super::{IO_FLOAT_BUF, IO_INT_BUF, RuntimeFuncIndices};
pub(super) fn emit_str_eq() -> Function {
let mut f = Function::new(vec![
(1, ValType::I32), (1, ValType::I32), (1, ValType::I32), ]);
f.instruction(&Instruction::LocalGet(0));
f.instruction(&Instruction::LocalGet(1));
f.instruction(&Instruction::I32Eq);
f.instruction(&Instruction::If(wasm_encoder::BlockType::Result(
ValType::I32,
)));
f.instruction(&Instruction::I32Const(1));
f.instruction(&Instruction::Else);
f.instruction(&Instruction::LocalGet(0));
f.instruction(&Instruction::I64Load(wasm_encoder::MemArg {
offset: 0,
align: 3,
memory_index: 0,
}));
f.instruction(&Instruction::I64Const(0xFFFFFFFF));
f.instruction(&Instruction::I64And);
f.instruction(&Instruction::I32WrapI64);
f.instruction(&Instruction::LocalSet(2));
f.instruction(&Instruction::LocalGet(1));
f.instruction(&Instruction::I64Load(wasm_encoder::MemArg {
offset: 0,
align: 3,
memory_index: 0,
}));
f.instruction(&Instruction::I64Const(0xFFFFFFFF));
f.instruction(&Instruction::I64And);
f.instruction(&Instruction::I32WrapI64);
f.instruction(&Instruction::LocalSet(3));
f.instruction(&Instruction::LocalGet(2));
f.instruction(&Instruction::LocalGet(3));
f.instruction(&Instruction::I32Ne);
f.instruction(&Instruction::If(wasm_encoder::BlockType::Result(
ValType::I32,
)));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::Else);
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::LocalSet(4));
f.instruction(&Instruction::Block(wasm_encoder::BlockType::Empty));
f.instruction(&Instruction::Loop(wasm_encoder::BlockType::Empty));
f.instruction(&Instruction::LocalGet(4));
f.instruction(&Instruction::LocalGet(2));
f.instruction(&Instruction::I32GeU);
f.instruction(&Instruction::BrIf(1));
f.instruction(&Instruction::LocalGet(0));
f.instruction(&Instruction::LocalGet(4));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::I32Load8U(wasm_encoder::MemArg {
offset: 8,
align: 0,
memory_index: 0,
}));
f.instruction(&Instruction::LocalGet(1));
f.instruction(&Instruction::LocalGet(4));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::I32Load8U(wasm_encoder::MemArg {
offset: 8,
align: 0,
memory_index: 0,
}));
f.instruction(&Instruction::I32Ne);
f.instruction(&Instruction::If(wasm_encoder::BlockType::Empty));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::Return);
f.instruction(&Instruction::End);
f.instruction(&Instruction::LocalGet(4));
f.instruction(&Instruction::I32Const(1));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::LocalSet(4));
f.instruction(&Instruction::Br(0)); f.instruction(&Instruction::End); f.instruction(&Instruction::End); f.instruction(&Instruction::I32Const(1));
f.instruction(&Instruction::End); f.instruction(&Instruction::End); f.instruction(&Instruction::End); f
}
pub(super) fn emit_str_len() -> Function {
let mut f = Function::new(vec![
(1, ValType::I32),
(1, ValType::I32),
(1, ValType::I32),
(1, ValType::I32),
(1, ValType::I32),
]);
emit_load_string_byte_len(&mut f, 0, 1);
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::LocalSet(2));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::LocalSet(3));
f.instruction(&Instruction::Block(wasm_encoder::BlockType::Empty));
f.instruction(&Instruction::Loop(wasm_encoder::BlockType::Empty));
f.instruction(&Instruction::LocalGet(2));
f.instruction(&Instruction::LocalGet(1));
f.instruction(&Instruction::I32GeU);
f.instruction(&Instruction::BrIf(1));
f.instruction(&Instruction::LocalGet(0));
f.instruction(&Instruction::LocalGet(2));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::I32Load8U(wasm_encoder::MemArg {
offset: 8,
align: 0,
memory_index: 0,
}));
f.instruction(&Instruction::LocalSet(4));
emit_set_utf8_char_width(&mut f, 4, 5);
f.instruction(&Instruction::LocalGet(2));
f.instruction(&Instruction::LocalGet(5));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::LocalSet(2));
f.instruction(&Instruction::LocalGet(3));
f.instruction(&Instruction::I32Const(1));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::LocalSet(3));
f.instruction(&Instruction::Br(0));
f.instruction(&Instruction::End);
f.instruction(&Instruction::End);
f.instruction(&Instruction::LocalGet(3));
f.instruction(&Instruction::I64ExtendI32U);
f.instruction(&Instruction::End);
f
}
pub(super) fn emit_str_byte_len() -> Function {
let mut f = Function::new(vec![]);
f.instruction(&Instruction::LocalGet(0));
f.instruction(&Instruction::I64Load(wasm_encoder::MemArg {
offset: 0,
align: 3,
memory_index: 0,
}));
f.instruction(&Instruction::I64Const(0xFFFFFFFF));
f.instruction(&Instruction::I64And);
f.instruction(&Instruction::End);
f
}
pub(super) fn emit_str_find(_rt: &RuntimeFuncIndices) -> Function {
let mut f = Function::new(vec![(7, ValType::I32)]);
emit_load_string_byte_len(&mut f, 0, 3);
emit_load_string_byte_len(&mut f, 1, 4);
f.instruction(&Instruction::LocalGet(2));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::I32LtS);
f.instruction(&Instruction::If(wasm_encoder::BlockType::Result(
ValType::I32,
)));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::Else);
f.instruction(&Instruction::LocalGet(2));
f.instruction(&Instruction::End);
f.instruction(&Instruction::LocalSet(5));
f.instruction(&Instruction::LocalGet(4));
f.instruction(&Instruction::I32Eqz);
f.instruction(&Instruction::If(wasm_encoder::BlockType::Empty));
f.instruction(&Instruction::LocalGet(5));
f.instruction(&Instruction::LocalGet(3));
f.instruction(&Instruction::I32LeU);
f.instruction(&Instruction::If(wasm_encoder::BlockType::Result(
ValType::I32,
)));
f.instruction(&Instruction::LocalGet(5));
f.instruction(&Instruction::Else);
f.instruction(&Instruction::LocalGet(3));
f.instruction(&Instruction::End);
f.instruction(&Instruction::Return);
f.instruction(&Instruction::End);
f.instruction(&Instruction::LocalGet(3));
f.instruction(&Instruction::LocalGet(4));
f.instruction(&Instruction::I32LtU);
f.instruction(&Instruction::If(wasm_encoder::BlockType::Empty));
f.instruction(&Instruction::I32Const(-1));
f.instruction(&Instruction::Return);
f.instruction(&Instruction::End);
f.instruction(&Instruction::LocalGet(3));
f.instruction(&Instruction::LocalGet(4));
f.instruction(&Instruction::I32Sub);
f.instruction(&Instruction::LocalSet(6));
f.instruction(&Instruction::LocalGet(5));
f.instruction(&Instruction::LocalGet(6));
f.instruction(&Instruction::I32GtU);
f.instruction(&Instruction::If(wasm_encoder::BlockType::Empty));
f.instruction(&Instruction::I32Const(-1));
f.instruction(&Instruction::Return);
f.instruction(&Instruction::End);
f.instruction(&Instruction::LocalGet(5));
f.instruction(&Instruction::LocalSet(7));
f.instruction(&Instruction::Block(wasm_encoder::BlockType::Empty));
f.instruction(&Instruction::Loop(wasm_encoder::BlockType::Empty));
f.instruction(&Instruction::LocalGet(7));
f.instruction(&Instruction::LocalGet(6));
f.instruction(&Instruction::I32GtU);
f.instruction(&Instruction::BrIf(1));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::LocalSet(8));
f.instruction(&Instruction::I32Const(1));
f.instruction(&Instruction::LocalSet(9));
f.instruction(&Instruction::Block(wasm_encoder::BlockType::Empty));
f.instruction(&Instruction::Loop(wasm_encoder::BlockType::Empty));
f.instruction(&Instruction::LocalGet(8));
f.instruction(&Instruction::LocalGet(4));
f.instruction(&Instruction::I32GeU);
f.instruction(&Instruction::BrIf(1));
f.instruction(&Instruction::LocalGet(0));
f.instruction(&Instruction::LocalGet(7));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::LocalGet(8));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::I32Load8U(wasm_encoder::MemArg {
offset: 8,
align: 0,
memory_index: 0,
}));
f.instruction(&Instruction::LocalGet(1));
f.instruction(&Instruction::LocalGet(8));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::I32Load8U(wasm_encoder::MemArg {
offset: 8,
align: 0,
memory_index: 0,
}));
f.instruction(&Instruction::I32Ne);
f.instruction(&Instruction::If(wasm_encoder::BlockType::Empty));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::LocalSet(9));
f.instruction(&Instruction::Br(2));
f.instruction(&Instruction::End);
f.instruction(&Instruction::LocalGet(8));
f.instruction(&Instruction::I32Const(1));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::LocalSet(8));
f.instruction(&Instruction::Br(0));
f.instruction(&Instruction::End);
f.instruction(&Instruction::End);
f.instruction(&Instruction::LocalGet(9));
f.instruction(&Instruction::If(wasm_encoder::BlockType::Empty));
f.instruction(&Instruction::LocalGet(7));
f.instruction(&Instruction::Return);
f.instruction(&Instruction::End);
f.instruction(&Instruction::LocalGet(7));
f.instruction(&Instruction::I32Const(1));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::LocalSet(7));
f.instruction(&Instruction::Br(0));
f.instruction(&Instruction::End);
f.instruction(&Instruction::End);
f.instruction(&Instruction::I32Const(-1));
f.instruction(&Instruction::End);
f
}
pub(super) fn emit_str_starts_with(rt: &RuntimeFuncIndices) -> Function {
let mut f = Function::new(vec![]);
f.instruction(&Instruction::LocalGet(0));
f.instruction(&Instruction::LocalGet(1));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::Call(rt.str_find));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::I32Eq);
f.instruction(&Instruction::End);
f
}
pub(super) fn emit_str_ends_with(rt: &RuntimeFuncIndices) -> Function {
let mut f = Function::new(vec![(3, ValType::I32)]);
emit_load_string_byte_len(&mut f, 0, 2);
emit_load_string_byte_len(&mut f, 1, 3);
f.instruction(&Instruction::LocalGet(3));
f.instruction(&Instruction::LocalGet(2));
f.instruction(&Instruction::I32GtU);
f.instruction(&Instruction::If(wasm_encoder::BlockType::Empty));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::Return);
f.instruction(&Instruction::End);
f.instruction(&Instruction::LocalGet(2));
f.instruction(&Instruction::LocalGet(3));
f.instruction(&Instruction::I32Sub);
f.instruction(&Instruction::LocalSet(4));
f.instruction(&Instruction::LocalGet(0));
f.instruction(&Instruction::LocalGet(1));
f.instruction(&Instruction::LocalGet(4));
f.instruction(&Instruction::Call(rt.str_find));
f.instruction(&Instruction::LocalGet(4));
f.instruction(&Instruction::I32Eq);
f.instruction(&Instruction::End);
f
}
pub(super) fn emit_str_contains(rt: &RuntimeFuncIndices) -> Function {
let mut f = Function::new(vec![]);
f.instruction(&Instruction::LocalGet(0));
f.instruction(&Instruction::LocalGet(1));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::Call(rt.str_find));
f.instruction(&Instruction::I32Const(-1));
f.instruction(&Instruction::I32Ne);
f.instruction(&Instruction::End);
f
}
pub(super) fn emit_str_concat(rt: &RuntimeFuncIndices) -> Function {
let mut f = Function::new(vec![
(1, ValType::I32), (1, ValType::I32), (1, ValType::I32), (1, ValType::I32), ]);
f.instruction(&Instruction::LocalGet(0));
f.instruction(&Instruction::I64Load(wasm_encoder::MemArg {
offset: 0,
align: 3,
memory_index: 0,
}));
f.instruction(&Instruction::I64Const(0xFFFFFFFF));
f.instruction(&Instruction::I64And);
f.instruction(&Instruction::I32WrapI64);
f.instruction(&Instruction::LocalSet(2));
f.instruction(&Instruction::LocalGet(1));
f.instruction(&Instruction::I64Load(wasm_encoder::MemArg {
offset: 0,
align: 3,
memory_index: 0,
}));
f.instruction(&Instruction::I64Const(0xFFFFFFFF));
f.instruction(&Instruction::I64And);
f.instruction(&Instruction::I32WrapI64);
f.instruction(&Instruction::LocalSet(3));
f.instruction(&Instruction::LocalGet(2));
f.instruction(&Instruction::LocalGet(3));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::LocalSet(5));
f.instruction(&Instruction::I32Const(8));
f.instruction(&Instruction::LocalGet(5));
f.instruction(&Instruction::I32Const(7));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::I32Const(-8i32));
f.instruction(&Instruction::I32And);
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::Call(rt.alloc));
f.instruction(&Instruction::LocalSet(4));
f.instruction(&Instruction::LocalGet(4));
f.instruction(&Instruction::I64Const(
(OBJ_STRING << HDR_KIND_SHIFT) as i64,
));
f.instruction(&Instruction::LocalGet(5));
f.instruction(&Instruction::I64ExtendI32U);
f.instruction(&Instruction::I64Or);
f.instruction(&Instruction::I64Store(wasm_encoder::MemArg {
offset: 0,
align: 3,
memory_index: 0,
}));
f.instruction(&Instruction::LocalGet(4));
f.instruction(&Instruction::I32Const(8));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::LocalGet(0));
f.instruction(&Instruction::I32Const(8));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::LocalGet(2));
f.instruction(&Instruction::MemoryCopy {
src_mem: 0,
dst_mem: 0,
});
f.instruction(&Instruction::LocalGet(4));
f.instruction(&Instruction::I32Const(8));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::LocalGet(2));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::LocalGet(1));
f.instruction(&Instruction::I32Const(8));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::LocalGet(3));
f.instruction(&Instruction::MemoryCopy {
src_mem: 0,
dst_mem: 0,
});
f.instruction(&Instruction::LocalGet(4));
f.instruction(&Instruction::End);
f
}
pub(super) fn emit_i64_to_str_obj(rt: &RuntimeFuncIndices) -> Function {
let mut f = Function::new(vec![
(1, ValType::I32), (1, ValType::I32), (1, ValType::I32), (1, ValType::I32), ]);
f.instruction(&Instruction::LocalGet(0));
f.instruction(&Instruction::I32Const(IO_INT_BUF as i32));
f.instruction(&Instruction::Call(rt.int_to_str));
f.instruction(&Instruction::LocalSet(1)); f.instruction(&Instruction::LocalGet(1));
f.instruction(&Instruction::I32Const(16));
f.instruction(&Instruction::I32ShrU);
f.instruction(&Instruction::LocalSet(2));
f.instruction(&Instruction::LocalGet(1));
f.instruction(&Instruction::I32Const(0xFFFF));
f.instruction(&Instruction::I32And);
f.instruction(&Instruction::LocalSet(3));
f.instruction(&Instruction::I32Const(8));
f.instruction(&Instruction::LocalGet(3));
f.instruction(&Instruction::I32Const(7));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::I32Const(-8i32));
f.instruction(&Instruction::I32And);
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::Call(rt.alloc));
f.instruction(&Instruction::LocalSet(4));
f.instruction(&Instruction::LocalGet(4));
f.instruction(&Instruction::I64Const(
(OBJ_STRING << HDR_KIND_SHIFT) as i64,
));
f.instruction(&Instruction::LocalGet(3));
f.instruction(&Instruction::I64ExtendI32U);
f.instruction(&Instruction::I64Or);
f.instruction(&Instruction::I64Store(wasm_encoder::MemArg {
offset: 0,
align: 3,
memory_index: 0,
}));
f.instruction(&Instruction::LocalGet(4));
f.instruction(&Instruction::I32Const(8));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::I32Const(IO_INT_BUF as i32));
f.instruction(&Instruction::LocalGet(2));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::LocalGet(3));
f.instruction(&Instruction::MemoryCopy {
src_mem: 0,
dst_mem: 0,
});
f.instruction(&Instruction::LocalGet(4));
f.instruction(&Instruction::End);
f
}
pub(super) fn emit_f64_to_str_obj(rt: &RuntimeFuncIndices) -> Function {
let mut f = Function::new(vec![
(1, ValType::I32), (1, ValType::I32), (1, ValType::I32), (1, ValType::I32), ]);
f.instruction(&Instruction::LocalGet(0));
f.instruction(&Instruction::I32Const(IO_FLOAT_BUF as i32));
f.instruction(&Instruction::Call(rt.float_to_str));
f.instruction(&Instruction::LocalSet(1));
f.instruction(&Instruction::LocalGet(1));
f.instruction(&Instruction::I32Const(16));
f.instruction(&Instruction::I32ShrU);
f.instruction(&Instruction::LocalSet(2));
f.instruction(&Instruction::LocalGet(1));
f.instruction(&Instruction::I32Const(0xFFFF));
f.instruction(&Instruction::I32And);
f.instruction(&Instruction::LocalSet(3));
f.instruction(&Instruction::I32Const(8));
f.instruction(&Instruction::LocalGet(3));
f.instruction(&Instruction::I32Const(7));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::I32Const(-8i32));
f.instruction(&Instruction::I32And);
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::Call(rt.alloc));
f.instruction(&Instruction::LocalSet(4));
f.instruction(&Instruction::LocalGet(4));
f.instruction(&Instruction::I64Const(
(OBJ_STRING << HDR_KIND_SHIFT) as i64,
));
f.instruction(&Instruction::LocalGet(3));
f.instruction(&Instruction::I64ExtendI32U);
f.instruction(&Instruction::I64Or);
f.instruction(&Instruction::I64Store(wasm_encoder::MemArg {
offset: 0,
align: 3,
memory_index: 0,
}));
f.instruction(&Instruction::LocalGet(4));
f.instruction(&Instruction::I32Const(8));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::I32Const(IO_FLOAT_BUF as i32));
f.instruction(&Instruction::LocalGet(2));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::LocalGet(3));
f.instruction(&Instruction::MemoryCopy {
src_mem: 0,
dst_mem: 0,
});
f.instruction(&Instruction::LocalGet(4));
f.instruction(&Instruction::End);
f
}
pub fn emit_str_char_at(rt: &RuntimeFuncIndices) -> Function {
let mut f = Function::new(vec![(7, ValType::I32)]);
f.instruction(&Instruction::LocalGet(1));
f.instruction(&Instruction::I64Const(0));
f.instruction(&Instruction::I64LtS);
f.instruction(&Instruction::If(wasm_encoder::BlockType::Empty));
f.instruction(&Instruction::I32Const(NONE_SENTINEL));
f.instruction(&Instruction::Return);
f.instruction(&Instruction::End);
emit_load_string_byte_len(&mut f, 0, 2);
f.instruction(&Instruction::LocalGet(1));
f.instruction(&Instruction::I32WrapI64);
f.instruction(&Instruction::LocalSet(3));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::LocalSet(4));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::LocalSet(5));
f.instruction(&Instruction::Block(wasm_encoder::BlockType::Empty));
f.instruction(&Instruction::Loop(wasm_encoder::BlockType::Empty));
f.instruction(&Instruction::LocalGet(4));
f.instruction(&Instruction::LocalGet(2));
f.instruction(&Instruction::I32GeU);
f.instruction(&Instruction::BrIf(1));
f.instruction(&Instruction::LocalGet(0));
f.instruction(&Instruction::LocalGet(4));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::I32Load8U(wasm_encoder::MemArg {
offset: 8,
align: 0,
memory_index: 0,
}));
f.instruction(&Instruction::LocalSet(6));
emit_set_utf8_char_width(&mut f, 6, 7);
f.instruction(&Instruction::LocalGet(5));
f.instruction(&Instruction::LocalGet(3));
f.instruction(&Instruction::I32Eq);
f.instruction(&Instruction::If(wasm_encoder::BlockType::Empty));
emit_alloc_string(&mut f, rt, 7, 8);
f.instruction(&Instruction::LocalGet(8));
f.instruction(&Instruction::I32Const(8));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::LocalGet(0));
f.instruction(&Instruction::I32Const(8));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::LocalGet(4));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::LocalGet(7));
f.instruction(&Instruction::MemoryCopy {
src_mem: 0,
dst_mem: 0,
});
f.instruction(&Instruction::I32Const(WRAP_SOME as i32));
f.instruction(&Instruction::LocalGet(8));
f.instruction(&Instruction::I32Const(1));
f.instruction(&Instruction::Call(rt.wrap_i32));
f.instruction(&Instruction::Return);
f.instruction(&Instruction::End);
f.instruction(&Instruction::LocalGet(4));
f.instruction(&Instruction::LocalGet(7));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::LocalSet(4));
f.instruction(&Instruction::LocalGet(5));
f.instruction(&Instruction::I32Const(1));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::LocalSet(5));
f.instruction(&Instruction::Br(0));
f.instruction(&Instruction::End);
f.instruction(&Instruction::End);
f.instruction(&Instruction::I32Const(NONE_SENTINEL));
f.instruction(&Instruction::End);
f
}
pub fn emit_char_from_code(rt: &RuntimeFuncIndices) -> Function {
let mut f = Function::new(vec![(3, ValType::I32)]);
f.instruction(&Instruction::LocalGet(0));
f.instruction(&Instruction::I64Const(0));
f.instruction(&Instruction::I64LtS);
f.instruction(&Instruction::LocalGet(0));
f.instruction(&Instruction::I64Const(0x10FFFF));
f.instruction(&Instruction::I64GtS);
f.instruction(&Instruction::I32Or);
f.instruction(&Instruction::LocalGet(0));
f.instruction(&Instruction::I64Const(0xD800));
f.instruction(&Instruction::I64GeS);
f.instruction(&Instruction::LocalGet(0));
f.instruction(&Instruction::I64Const(0xDFFF));
f.instruction(&Instruction::I64LeS);
f.instruction(&Instruction::I32And);
f.instruction(&Instruction::I32Or);
f.instruction(&Instruction::If(wasm_encoder::BlockType::Result(
ValType::I32,
)));
f.instruction(&Instruction::I32Const(NONE_SENTINEL));
f.instruction(&Instruction::Else);
f.instruction(&Instruction::LocalGet(0));
f.instruction(&Instruction::I32WrapI64);
f.instruction(&Instruction::LocalSet(1));
f.instruction(&Instruction::LocalGet(1));
f.instruction(&Instruction::I32Const(0x80));
f.instruction(&Instruction::I32LtU);
f.instruction(&Instruction::If(wasm_encoder::BlockType::Result(
ValType::I32,
)));
f.instruction(&Instruction::I32Const(1));
f.instruction(&Instruction::Else);
f.instruction(&Instruction::LocalGet(1));
f.instruction(&Instruction::I32Const(0x800));
f.instruction(&Instruction::I32LtU);
f.instruction(&Instruction::If(wasm_encoder::BlockType::Result(
ValType::I32,
)));
f.instruction(&Instruction::I32Const(2));
f.instruction(&Instruction::Else);
f.instruction(&Instruction::LocalGet(1));
f.instruction(&Instruction::I32Const(0x10000));
f.instruction(&Instruction::I32LtU);
f.instruction(&Instruction::If(wasm_encoder::BlockType::Result(
ValType::I32,
)));
f.instruction(&Instruction::I32Const(3));
f.instruction(&Instruction::Else);
f.instruction(&Instruction::I32Const(4));
f.instruction(&Instruction::End);
f.instruction(&Instruction::End);
f.instruction(&Instruction::End);
f.instruction(&Instruction::LocalSet(2));
emit_alloc_string(&mut f, rt, 2, 3);
f.instruction(&Instruction::LocalGet(2));
f.instruction(&Instruction::I32Const(1));
f.instruction(&Instruction::I32Eq);
f.instruction(&Instruction::If(wasm_encoder::BlockType::Empty));
f.instruction(&Instruction::LocalGet(3));
f.instruction(&Instruction::LocalGet(1));
f.instruction(&Instruction::I32Store8(wasm_encoder::MemArg {
offset: 8,
align: 0,
memory_index: 0,
}));
f.instruction(&Instruction::Else);
f.instruction(&Instruction::LocalGet(2));
f.instruction(&Instruction::I32Const(2));
f.instruction(&Instruction::I32Eq);
f.instruction(&Instruction::If(wasm_encoder::BlockType::Empty));
f.instruction(&Instruction::LocalGet(3));
f.instruction(&Instruction::LocalGet(1));
f.instruction(&Instruction::I32Const(6));
f.instruction(&Instruction::I32ShrU);
f.instruction(&Instruction::I32Const(0xC0));
f.instruction(&Instruction::I32Or);
f.instruction(&Instruction::I32Store8(wasm_encoder::MemArg {
offset: 8,
align: 0,
memory_index: 0,
}));
f.instruction(&Instruction::LocalGet(3));
f.instruction(&Instruction::LocalGet(1));
f.instruction(&Instruction::I32Const(0x3F));
f.instruction(&Instruction::I32And);
f.instruction(&Instruction::I32Const(0x80));
f.instruction(&Instruction::I32Or);
f.instruction(&Instruction::I32Store8(wasm_encoder::MemArg {
offset: 9,
align: 0,
memory_index: 0,
}));
f.instruction(&Instruction::Else);
f.instruction(&Instruction::LocalGet(2));
f.instruction(&Instruction::I32Const(3));
f.instruction(&Instruction::I32Eq);
f.instruction(&Instruction::If(wasm_encoder::BlockType::Empty));
f.instruction(&Instruction::LocalGet(3));
f.instruction(&Instruction::LocalGet(1));
f.instruction(&Instruction::I32Const(12));
f.instruction(&Instruction::I32ShrU);
f.instruction(&Instruction::I32Const(0xE0));
f.instruction(&Instruction::I32Or);
f.instruction(&Instruction::I32Store8(wasm_encoder::MemArg {
offset: 8,
align: 0,
memory_index: 0,
}));
f.instruction(&Instruction::LocalGet(3));
f.instruction(&Instruction::LocalGet(1));
f.instruction(&Instruction::I32Const(6));
f.instruction(&Instruction::I32ShrU);
f.instruction(&Instruction::I32Const(0x3F));
f.instruction(&Instruction::I32And);
f.instruction(&Instruction::I32Const(0x80));
f.instruction(&Instruction::I32Or);
f.instruction(&Instruction::I32Store8(wasm_encoder::MemArg {
offset: 9,
align: 0,
memory_index: 0,
}));
f.instruction(&Instruction::LocalGet(3));
f.instruction(&Instruction::LocalGet(1));
f.instruction(&Instruction::I32Const(0x3F));
f.instruction(&Instruction::I32And);
f.instruction(&Instruction::I32Const(0x80));
f.instruction(&Instruction::I32Or);
f.instruction(&Instruction::I32Store8(wasm_encoder::MemArg {
offset: 10,
align: 0,
memory_index: 0,
}));
f.instruction(&Instruction::Else);
f.instruction(&Instruction::LocalGet(3));
f.instruction(&Instruction::LocalGet(1));
f.instruction(&Instruction::I32Const(18));
f.instruction(&Instruction::I32ShrU);
f.instruction(&Instruction::I32Const(0xF0));
f.instruction(&Instruction::I32Or);
f.instruction(&Instruction::I32Store8(wasm_encoder::MemArg {
offset: 8,
align: 0,
memory_index: 0,
}));
f.instruction(&Instruction::LocalGet(3));
f.instruction(&Instruction::LocalGet(1));
f.instruction(&Instruction::I32Const(12));
f.instruction(&Instruction::I32ShrU);
f.instruction(&Instruction::I32Const(0x3F));
f.instruction(&Instruction::I32And);
f.instruction(&Instruction::I32Const(0x80));
f.instruction(&Instruction::I32Or);
f.instruction(&Instruction::I32Store8(wasm_encoder::MemArg {
offset: 9,
align: 0,
memory_index: 0,
}));
f.instruction(&Instruction::LocalGet(3));
f.instruction(&Instruction::LocalGet(1));
f.instruction(&Instruction::I32Const(6));
f.instruction(&Instruction::I32ShrU);
f.instruction(&Instruction::I32Const(0x3F));
f.instruction(&Instruction::I32And);
f.instruction(&Instruction::I32Const(0x80));
f.instruction(&Instruction::I32Or);
f.instruction(&Instruction::I32Store8(wasm_encoder::MemArg {
offset: 10,
align: 0,
memory_index: 0,
}));
f.instruction(&Instruction::LocalGet(3));
f.instruction(&Instruction::LocalGet(1));
f.instruction(&Instruction::I32Const(0x3F));
f.instruction(&Instruction::I32And);
f.instruction(&Instruction::I32Const(0x80));
f.instruction(&Instruction::I32Or);
f.instruction(&Instruction::I32Store8(wasm_encoder::MemArg {
offset: 11,
align: 0,
memory_index: 0,
}));
f.instruction(&Instruction::End);
f.instruction(&Instruction::End);
f.instruction(&Instruction::End);
f.instruction(&Instruction::I32Const(WRAP_SOME as i32));
f.instruction(&Instruction::LocalGet(3));
f.instruction(&Instruction::I32Const(1));
f.instruction(&Instruction::Call(rt.wrap_i32));
f.instruction(&Instruction::End);
f.instruction(&Instruction::End);
f
}
pub fn emit_char_to_code() -> Function {
let mut f = Function::new(vec![(6, ValType::I32)]);
emit_load_string_byte_len(&mut f, 0, 1);
f.instruction(&Instruction::LocalGet(1));
f.instruction(&Instruction::I32Eqz);
f.instruction(&Instruction::If(wasm_encoder::BlockType::Empty));
f.instruction(&Instruction::Unreachable);
f.instruction(&Instruction::End);
f.instruction(&Instruction::LocalGet(0));
f.instruction(&Instruction::I32Load8U(wasm_encoder::MemArg {
offset: 8,
align: 0,
memory_index: 0,
}));
f.instruction(&Instruction::LocalSet(2));
f.instruction(&Instruction::LocalGet(2));
f.instruction(&Instruction::I32Const(0x80));
f.instruction(&Instruction::I32LtU);
f.instruction(&Instruction::If(wasm_encoder::BlockType::Empty));
f.instruction(&Instruction::LocalGet(2));
f.instruction(&Instruction::LocalSet(6));
f.instruction(&Instruction::Else);
f.instruction(&Instruction::LocalGet(2));
f.instruction(&Instruction::I32Const(0xE0));
f.instruction(&Instruction::I32LtU);
f.instruction(&Instruction::If(wasm_encoder::BlockType::Empty));
f.instruction(&Instruction::LocalGet(1));
f.instruction(&Instruction::I32Const(2));
f.instruction(&Instruction::I32LtU);
f.instruction(&Instruction::If(wasm_encoder::BlockType::Empty));
f.instruction(&Instruction::Unreachable);
f.instruction(&Instruction::End);
f.instruction(&Instruction::LocalGet(0));
f.instruction(&Instruction::I32Load8U(wasm_encoder::MemArg {
offset: 9,
align: 0,
memory_index: 0,
}));
f.instruction(&Instruction::LocalSet(3));
f.instruction(&Instruction::LocalGet(2));
f.instruction(&Instruction::I32Const(0x1F));
f.instruction(&Instruction::I32And);
f.instruction(&Instruction::I32Const(6));
f.instruction(&Instruction::I32Shl);
f.instruction(&Instruction::LocalGet(3));
f.instruction(&Instruction::I32Const(0x3F));
f.instruction(&Instruction::I32And);
f.instruction(&Instruction::I32Or);
f.instruction(&Instruction::LocalSet(6));
f.instruction(&Instruction::Else);
f.instruction(&Instruction::LocalGet(2));
f.instruction(&Instruction::I32Const(0xF0));
f.instruction(&Instruction::I32LtU);
f.instruction(&Instruction::If(wasm_encoder::BlockType::Empty));
f.instruction(&Instruction::LocalGet(1));
f.instruction(&Instruction::I32Const(3));
f.instruction(&Instruction::I32LtU);
f.instruction(&Instruction::If(wasm_encoder::BlockType::Empty));
f.instruction(&Instruction::Unreachable);
f.instruction(&Instruction::End);
f.instruction(&Instruction::LocalGet(0));
f.instruction(&Instruction::I32Load8U(wasm_encoder::MemArg {
offset: 9,
align: 0,
memory_index: 0,
}));
f.instruction(&Instruction::LocalSet(3));
f.instruction(&Instruction::LocalGet(0));
f.instruction(&Instruction::I32Load8U(wasm_encoder::MemArg {
offset: 10,
align: 0,
memory_index: 0,
}));
f.instruction(&Instruction::LocalSet(4));
f.instruction(&Instruction::LocalGet(2));
f.instruction(&Instruction::I32Const(0x0F));
f.instruction(&Instruction::I32And);
f.instruction(&Instruction::I32Const(12));
f.instruction(&Instruction::I32Shl);
f.instruction(&Instruction::LocalGet(3));
f.instruction(&Instruction::I32Const(0x3F));
f.instruction(&Instruction::I32And);
f.instruction(&Instruction::I32Const(6));
f.instruction(&Instruction::I32Shl);
f.instruction(&Instruction::I32Or);
f.instruction(&Instruction::LocalGet(4));
f.instruction(&Instruction::I32Const(0x3F));
f.instruction(&Instruction::I32And);
f.instruction(&Instruction::I32Or);
f.instruction(&Instruction::LocalSet(6));
f.instruction(&Instruction::Else);
f.instruction(&Instruction::LocalGet(1));
f.instruction(&Instruction::I32Const(4));
f.instruction(&Instruction::I32LtU);
f.instruction(&Instruction::If(wasm_encoder::BlockType::Empty));
f.instruction(&Instruction::Unreachable);
f.instruction(&Instruction::End);
f.instruction(&Instruction::LocalGet(0));
f.instruction(&Instruction::I32Load8U(wasm_encoder::MemArg {
offset: 9,
align: 0,
memory_index: 0,
}));
f.instruction(&Instruction::LocalSet(3));
f.instruction(&Instruction::LocalGet(0));
f.instruction(&Instruction::I32Load8U(wasm_encoder::MemArg {
offset: 10,
align: 0,
memory_index: 0,
}));
f.instruction(&Instruction::LocalSet(4));
f.instruction(&Instruction::LocalGet(0));
f.instruction(&Instruction::I32Load8U(wasm_encoder::MemArg {
offset: 11,
align: 0,
memory_index: 0,
}));
f.instruction(&Instruction::LocalSet(5));
f.instruction(&Instruction::LocalGet(2));
f.instruction(&Instruction::I32Const(0x07));
f.instruction(&Instruction::I32And);
f.instruction(&Instruction::I32Const(18));
f.instruction(&Instruction::I32Shl);
f.instruction(&Instruction::LocalGet(3));
f.instruction(&Instruction::I32Const(0x3F));
f.instruction(&Instruction::I32And);
f.instruction(&Instruction::I32Const(12));
f.instruction(&Instruction::I32Shl);
f.instruction(&Instruction::I32Or);
f.instruction(&Instruction::LocalGet(4));
f.instruction(&Instruction::I32Const(0x3F));
f.instruction(&Instruction::I32And);
f.instruction(&Instruction::I32Const(6));
f.instruction(&Instruction::I32Shl);
f.instruction(&Instruction::I32Or);
f.instruction(&Instruction::LocalGet(5));
f.instruction(&Instruction::I32Const(0x3F));
f.instruction(&Instruction::I32And);
f.instruction(&Instruction::I32Or);
f.instruction(&Instruction::LocalSet(6));
f.instruction(&Instruction::End);
f.instruction(&Instruction::End);
f.instruction(&Instruction::End);
f.instruction(&Instruction::LocalGet(6));
f.instruction(&Instruction::I64ExtendI32U);
f.instruction(&Instruction::End);
f
}
pub fn emit_byte_to_hex(rt: &RuntimeFuncIndices) -> Function {
let mut f = Function::new(vec![(4, ValType::I32)]);
f.instruction(&Instruction::LocalGet(0));
f.instruction(&Instruction::I64Const(0));
f.instruction(&Instruction::I64LtS);
f.instruction(&Instruction::LocalGet(0));
f.instruction(&Instruction::I64Const(255));
f.instruction(&Instruction::I64GtS);
f.instruction(&Instruction::I32Or);
f.instruction(&Instruction::If(wasm_encoder::BlockType::Empty));
emit_return_err_empty_string(&mut f, rt, 2);
f.instruction(&Instruction::End);
f.instruction(&Instruction::LocalGet(0));
f.instruction(&Instruction::I32WrapI64);
f.instruction(&Instruction::LocalSet(1));
f.instruction(&Instruction::I32Const(2));
f.instruction(&Instruction::LocalSet(3));
emit_alloc_string(&mut f, rt, 3, 2);
f.instruction(&Instruction::LocalGet(1));
f.instruction(&Instruction::I32Const(4));
f.instruction(&Instruction::I32ShrU);
f.instruction(&Instruction::I32Const(0xF));
f.instruction(&Instruction::I32And);
f.instruction(&Instruction::LocalSet(4));
f.instruction(&Instruction::LocalGet(2));
emit_push_hex_char(&mut f, 4);
f.instruction(&Instruction::I32Store8(wasm_encoder::MemArg {
offset: 8,
align: 0,
memory_index: 0,
}));
f.instruction(&Instruction::LocalGet(1));
f.instruction(&Instruction::I32Const(0xF));
f.instruction(&Instruction::I32And);
f.instruction(&Instruction::LocalSet(4));
f.instruction(&Instruction::LocalGet(2));
emit_push_hex_char(&mut f, 4);
f.instruction(&Instruction::I32Store8(wasm_encoder::MemArg {
offset: 9,
align: 0,
memory_index: 0,
}));
f.instruction(&Instruction::I32Const(WRAP_OK as i32));
f.instruction(&Instruction::LocalGet(2));
f.instruction(&Instruction::I32Const(1));
f.instruction(&Instruction::Call(rt.wrap_i32));
f.instruction(&Instruction::End);
f
}
pub fn emit_byte_from_hex(rt: &RuntimeFuncIndices) -> Function {
let mut f = Function::new(vec![(5, ValType::I32)]);
emit_load_string_byte_len(&mut f, 0, 1);
f.instruction(&Instruction::LocalGet(1));
f.instruction(&Instruction::I32Const(2));
f.instruction(&Instruction::I32Ne);
f.instruction(&Instruction::If(wasm_encoder::BlockType::Empty));
emit_return_err_empty_string(&mut f, rt, 5);
f.instruction(&Instruction::End);
f.instruction(&Instruction::LocalGet(0));
f.instruction(&Instruction::I32Load8U(wasm_encoder::MemArg {
offset: 8,
align: 0,
memory_index: 0,
}));
f.instruction(&Instruction::LocalSet(4));
emit_set_hex_nibble(&mut f, rt, 4, 2, 5);
f.instruction(&Instruction::LocalGet(0));
f.instruction(&Instruction::I32Load8U(wasm_encoder::MemArg {
offset: 9,
align: 0,
memory_index: 0,
}));
f.instruction(&Instruction::LocalSet(4));
emit_set_hex_nibble(&mut f, rt, 4, 3, 5);
f.instruction(&Instruction::LocalGet(2));
f.instruction(&Instruction::I32Const(4));
f.instruction(&Instruction::I32Shl);
f.instruction(&Instruction::LocalGet(3));
f.instruction(&Instruction::I32Or);
f.instruction(&Instruction::LocalSet(5));
f.instruction(&Instruction::I32Const(WRAP_OK as i32));
f.instruction(&Instruction::LocalGet(5));
f.instruction(&Instruction::I64ExtendI32U);
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::Call(rt.wrap));
f.instruction(&Instruction::End);
f
}
pub fn emit_str_trim(rt: &RuntimeFuncIndices) -> Function {
let mut f = Function::new(vec![
(1, ValType::I32),
(1, ValType::I32),
(1, ValType::I32),
(1, ValType::I32),
(1, ValType::I32),
(1, ValType::I32),
]);
f.instruction(&Instruction::LocalGet(0));
f.instruction(&Instruction::I64Load(wasm_encoder::MemArg {
offset: 0,
align: 3,
memory_index: 0,
}));
f.instruction(&Instruction::I64Const(0xFFFFFFFF));
f.instruction(&Instruction::I64And);
f.instruction(&Instruction::I32WrapI64);
f.instruction(&Instruction::LocalSet(1));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::LocalSet(2));
f.instruction(&Instruction::Block(wasm_encoder::BlockType::Empty));
f.instruction(&Instruction::Loop(wasm_encoder::BlockType::Empty));
f.instruction(&Instruction::LocalGet(2));
f.instruction(&Instruction::LocalGet(1));
f.instruction(&Instruction::I32GeU);
f.instruction(&Instruction::BrIf(1));
f.instruction(&Instruction::LocalGet(0));
f.instruction(&Instruction::LocalGet(2));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::I32Load8U(wasm_encoder::MemArg {
offset: 8,
align: 0,
memory_index: 0,
}));
f.instruction(&Instruction::LocalSet(4));
emit_is_whitespace(&mut f, 4);
f.instruction(&Instruction::I32Eqz);
f.instruction(&Instruction::BrIf(1));
f.instruction(&Instruction::LocalGet(2));
f.instruction(&Instruction::I32Const(1));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::LocalSet(2));
f.instruction(&Instruction::Br(0));
f.instruction(&Instruction::End);
f.instruction(&Instruction::End);
f.instruction(&Instruction::LocalGet(1));
f.instruction(&Instruction::LocalSet(3));
f.instruction(&Instruction::Block(wasm_encoder::BlockType::Empty));
f.instruction(&Instruction::Loop(wasm_encoder::BlockType::Empty));
f.instruction(&Instruction::LocalGet(3));
f.instruction(&Instruction::LocalGet(2));
f.instruction(&Instruction::I32LeU);
f.instruction(&Instruction::BrIf(1));
f.instruction(&Instruction::LocalGet(0));
f.instruction(&Instruction::LocalGet(3));
f.instruction(&Instruction::I32Const(1));
f.instruction(&Instruction::I32Sub);
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::I32Load8U(wasm_encoder::MemArg {
offset: 8,
align: 0,
memory_index: 0,
}));
f.instruction(&Instruction::LocalSet(4));
emit_is_whitespace(&mut f, 4);
f.instruction(&Instruction::I32Eqz);
f.instruction(&Instruction::BrIf(1));
f.instruction(&Instruction::LocalGet(3));
f.instruction(&Instruction::I32Const(1));
f.instruction(&Instruction::I32Sub);
f.instruction(&Instruction::LocalSet(3));
f.instruction(&Instruction::Br(0));
f.instruction(&Instruction::End);
f.instruction(&Instruction::End);
f.instruction(&Instruction::LocalGet(3));
f.instruction(&Instruction::LocalGet(2));
f.instruction(&Instruction::I32Sub);
f.instruction(&Instruction::LocalSet(5));
f.instruction(&Instruction::LocalGet(5));
f.instruction(&Instruction::LocalGet(1));
f.instruction(&Instruction::I32Eq);
f.instruction(&Instruction::If(wasm_encoder::BlockType::Result(
ValType::I32,
)));
f.instruction(&Instruction::LocalGet(0));
f.instruction(&Instruction::Else);
emit_alloc_string(&mut f, rt, 5, 6);
f.instruction(&Instruction::LocalGet(6));
f.instruction(&Instruction::I32Const(8));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::LocalGet(0));
f.instruction(&Instruction::I32Const(8));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::LocalGet(2));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::LocalGet(5));
f.instruction(&Instruction::MemoryCopy {
src_mem: 0,
dst_mem: 0,
});
f.instruction(&Instruction::LocalGet(6));
f.instruction(&Instruction::End);
f.instruction(&Instruction::End);
f
}
pub fn emit_str_slice(rt: &RuntimeFuncIndices) -> Function {
let mut f = Function::new(vec![(10, ValType::I32)]);
f.instruction(&Instruction::LocalGet(1));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::I32LtS);
f.instruction(&Instruction::If(wasm_encoder::BlockType::Result(
ValType::I32,
)));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::Else);
f.instruction(&Instruction::LocalGet(1));
f.instruction(&Instruction::End);
f.instruction(&Instruction::LocalSet(3));
f.instruction(&Instruction::LocalGet(2));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::I32LtS);
f.instruction(&Instruction::If(wasm_encoder::BlockType::Result(
ValType::I32,
)));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::Else);
f.instruction(&Instruction::LocalGet(2));
f.instruction(&Instruction::End);
f.instruction(&Instruction::LocalSet(4));
f.instruction(&Instruction::LocalGet(3));
f.instruction(&Instruction::LocalGet(4));
f.instruction(&Instruction::I32GeS);
f.instruction(&Instruction::If(wasm_encoder::BlockType::Empty));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::LocalSet(11));
emit_alloc_string(&mut f, rt, 11, 12);
f.instruction(&Instruction::LocalGet(12));
f.instruction(&Instruction::Return);
f.instruction(&Instruction::End);
emit_load_string_byte_len(&mut f, 0, 5);
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::LocalSet(6));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::LocalSet(7));
f.instruction(&Instruction::LocalGet(5));
f.instruction(&Instruction::LocalSet(8));
f.instruction(&Instruction::LocalGet(5));
f.instruction(&Instruction::LocalSet(9));
f.instruction(&Instruction::Block(wasm_encoder::BlockType::Empty));
f.instruction(&Instruction::Loop(wasm_encoder::BlockType::Empty));
f.instruction(&Instruction::LocalGet(7));
f.instruction(&Instruction::LocalGet(3));
f.instruction(&Instruction::I32Eq);
f.instruction(&Instruction::If(wasm_encoder::BlockType::Empty));
f.instruction(&Instruction::LocalGet(6));
f.instruction(&Instruction::LocalSet(8));
f.instruction(&Instruction::End);
f.instruction(&Instruction::LocalGet(7));
f.instruction(&Instruction::LocalGet(4));
f.instruction(&Instruction::I32Eq);
f.instruction(&Instruction::If(wasm_encoder::BlockType::Empty));
f.instruction(&Instruction::LocalGet(6));
f.instruction(&Instruction::LocalSet(9));
f.instruction(&Instruction::Br(2));
f.instruction(&Instruction::End);
f.instruction(&Instruction::LocalGet(6));
f.instruction(&Instruction::LocalGet(5));
f.instruction(&Instruction::I32GeU);
f.instruction(&Instruction::BrIf(1));
f.instruction(&Instruction::LocalGet(0));
f.instruction(&Instruction::LocalGet(6));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::I32Load8U(wasm_encoder::MemArg {
offset: 8,
align: 0,
memory_index: 0,
}));
f.instruction(&Instruction::LocalSet(10));
emit_set_utf8_char_width(&mut f, 10, 11);
f.instruction(&Instruction::LocalGet(6));
f.instruction(&Instruction::LocalGet(11));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::LocalSet(6));
f.instruction(&Instruction::LocalGet(7));
f.instruction(&Instruction::I32Const(1));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::LocalSet(7));
f.instruction(&Instruction::Br(0));
f.instruction(&Instruction::End);
f.instruction(&Instruction::End);
f.instruction(&Instruction::LocalGet(9));
f.instruction(&Instruction::LocalGet(8));
f.instruction(&Instruction::I32Sub);
f.instruction(&Instruction::LocalSet(11));
emit_alloc_string(&mut f, rt, 11, 12);
f.instruction(&Instruction::LocalGet(12));
f.instruction(&Instruction::I32Const(8));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::LocalGet(0));
f.instruction(&Instruction::I32Const(8));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::LocalGet(8));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::LocalGet(11));
f.instruction(&Instruction::MemoryCopy {
src_mem: 0,
dst_mem: 0,
});
f.instruction(&Instruction::LocalGet(12));
f.instruction(&Instruction::End);
f
}
pub fn emit_str_chars(rt: &RuntimeFuncIndices) -> Function {
let mut f = Function::new(vec![(6, ValType::I32)]);
emit_load_string_byte_len(&mut f, 0, 1);
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::LocalSet(2));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::LocalSet(3));
f.instruction(&Instruction::Block(wasm_encoder::BlockType::Empty));
f.instruction(&Instruction::Loop(wasm_encoder::BlockType::Empty));
f.instruction(&Instruction::LocalGet(2));
f.instruction(&Instruction::LocalGet(1));
f.instruction(&Instruction::I32GeU);
f.instruction(&Instruction::BrIf(1));
f.instruction(&Instruction::LocalGet(0));
f.instruction(&Instruction::LocalGet(2));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::I32Load8U(wasm_encoder::MemArg {
offset: 8,
align: 0,
memory_index: 0,
}));
f.instruction(&Instruction::LocalSet(4));
emit_set_utf8_char_width(&mut f, 4, 5);
emit_alloc_string(&mut f, rt, 5, 6);
f.instruction(&Instruction::LocalGet(6));
f.instruction(&Instruction::I32Const(8));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::LocalGet(0));
f.instruction(&Instruction::I32Const(8));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::LocalGet(2));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::LocalGet(5));
f.instruction(&Instruction::MemoryCopy {
src_mem: 0,
dst_mem: 0,
});
f.instruction(&Instruction::LocalGet(6));
f.instruction(&Instruction::I64ExtendI32U);
f.instruction(&Instruction::LocalGet(3));
f.instruction(&Instruction::I32Const(1));
f.instruction(&Instruction::Call(rt.list_cons));
f.instruction(&Instruction::LocalSet(3));
f.instruction(&Instruction::LocalGet(2));
f.instruction(&Instruction::LocalGet(5));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::LocalSet(2));
f.instruction(&Instruction::Br(0));
f.instruction(&Instruction::End);
f.instruction(&Instruction::End);
f.instruction(&Instruction::LocalGet(3));
f.instruction(&Instruction::Call(rt.list_reverse));
f.instruction(&Instruction::End);
f
}
pub fn emit_str_split(rt: &RuntimeFuncIndices) -> Function {
let mut f = Function::new(vec![(11, ValType::I32)]);
emit_load_string_byte_len(&mut f, 0, 2);
emit_load_string_byte_len(&mut f, 1, 3);
f.instruction(&Instruction::LocalGet(3));
f.instruction(&Instruction::I32Eqz);
f.instruction(&Instruction::If(wasm_encoder::BlockType::Empty));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::LocalSet(8));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::LocalSet(7));
emit_copy_string_range(&mut f, rt, 0, 5, 7, 9);
f.instruction(&Instruction::LocalGet(9));
f.instruction(&Instruction::I64ExtendI32U);
f.instruction(&Instruction::LocalGet(8));
f.instruction(&Instruction::I32Const(1));
f.instruction(&Instruction::Call(rt.list_cons));
f.instruction(&Instruction::LocalSet(8));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::LocalSet(10));
f.instruction(&Instruction::Block(wasm_encoder::BlockType::Empty));
f.instruction(&Instruction::Loop(wasm_encoder::BlockType::Empty));
f.instruction(&Instruction::LocalGet(10));
f.instruction(&Instruction::LocalGet(2));
f.instruction(&Instruction::I32GeU);
f.instruction(&Instruction::BrIf(1));
f.instruction(&Instruction::LocalGet(0));
f.instruction(&Instruction::LocalGet(10));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::I32Load8U(wasm_encoder::MemArg {
offset: 8,
align: 0,
memory_index: 0,
}));
f.instruction(&Instruction::LocalSet(11));
emit_set_utf8_char_width(&mut f, 11, 12);
f.instruction(&Instruction::LocalGet(10));
f.instruction(&Instruction::LocalSet(5));
f.instruction(&Instruction::LocalGet(12));
f.instruction(&Instruction::LocalSet(7));
emit_copy_string_range(&mut f, rt, 0, 5, 7, 9);
f.instruction(&Instruction::LocalGet(9));
f.instruction(&Instruction::I64ExtendI32U);
f.instruction(&Instruction::LocalGet(8));
f.instruction(&Instruction::I32Const(1));
f.instruction(&Instruction::Call(rt.list_cons));
f.instruction(&Instruction::LocalSet(8));
f.instruction(&Instruction::LocalGet(10));
f.instruction(&Instruction::LocalGet(12));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::LocalSet(10));
f.instruction(&Instruction::Br(0));
f.instruction(&Instruction::End);
f.instruction(&Instruction::End);
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::LocalSet(7));
emit_copy_string_range(&mut f, rt, 0, 5, 7, 9);
f.instruction(&Instruction::LocalGet(9));
f.instruction(&Instruction::I64ExtendI32U);
f.instruction(&Instruction::LocalGet(8));
f.instruction(&Instruction::I32Const(1));
f.instruction(&Instruction::Call(rt.list_cons));
f.instruction(&Instruction::LocalSet(8));
f.instruction(&Instruction::LocalGet(8));
f.instruction(&Instruction::Call(rt.list_reverse));
f.instruction(&Instruction::Return);
f.instruction(&Instruction::End);
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::LocalSet(8));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::LocalSet(4));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::LocalSet(5));
f.instruction(&Instruction::Block(wasm_encoder::BlockType::Empty));
f.instruction(&Instruction::Loop(wasm_encoder::BlockType::Empty));
f.instruction(&Instruction::LocalGet(0));
f.instruction(&Instruction::LocalGet(1));
f.instruction(&Instruction::LocalGet(4));
f.instruction(&Instruction::Call(rt.str_find));
f.instruction(&Instruction::LocalSet(6));
f.instruction(&Instruction::LocalGet(6));
f.instruction(&Instruction::I32Const(-1));
f.instruction(&Instruction::I32Eq);
f.instruction(&Instruction::BrIf(1));
f.instruction(&Instruction::LocalGet(6));
f.instruction(&Instruction::LocalGet(5));
f.instruction(&Instruction::I32Sub);
f.instruction(&Instruction::LocalSet(7));
emit_copy_string_range(&mut f, rt, 0, 5, 7, 9);
f.instruction(&Instruction::LocalGet(9));
f.instruction(&Instruction::I64ExtendI32U);
f.instruction(&Instruction::LocalGet(8));
f.instruction(&Instruction::I32Const(1));
f.instruction(&Instruction::Call(rt.list_cons));
f.instruction(&Instruction::LocalSet(8));
f.instruction(&Instruction::LocalGet(6));
f.instruction(&Instruction::LocalGet(3));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::LocalSet(4));
f.instruction(&Instruction::LocalGet(4));
f.instruction(&Instruction::LocalSet(5));
f.instruction(&Instruction::Br(0));
f.instruction(&Instruction::End);
f.instruction(&Instruction::End);
f.instruction(&Instruction::LocalGet(2));
f.instruction(&Instruction::LocalGet(5));
f.instruction(&Instruction::I32Sub);
f.instruction(&Instruction::LocalSet(7));
emit_copy_string_range(&mut f, rt, 0, 5, 7, 9);
f.instruction(&Instruction::LocalGet(9));
f.instruction(&Instruction::I64ExtendI32U);
f.instruction(&Instruction::LocalGet(8));
f.instruction(&Instruction::I32Const(1));
f.instruction(&Instruction::Call(rt.list_cons));
f.instruction(&Instruction::LocalSet(8));
f.instruction(&Instruction::LocalGet(8));
f.instruction(&Instruction::Call(rt.list_reverse));
f.instruction(&Instruction::End);
f
}
pub fn emit_str_join(rt: &RuntimeFuncIndices) -> Function {
let mut f = Function::new(vec![
(1, ValType::I32),
(1, ValType::I32),
(1, ValType::I32),
(1, ValType::I32),
(1, ValType::I32),
(1, ValType::I32),
(1, ValType::I32),
(1, ValType::I32),
]);
f.instruction(&Instruction::LocalGet(1));
f.instruction(&Instruction::I64Load(wasm_encoder::MemArg {
offset: 0,
align: 3,
memory_index: 0,
}));
f.instruction(&Instruction::I64Const(0xFFFFFFFF));
f.instruction(&Instruction::I64And);
f.instruction(&Instruction::I32WrapI64);
f.instruction(&Instruction::LocalSet(5));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::LocalSet(2));
f.instruction(&Instruction::LocalGet(0));
f.instruction(&Instruction::LocalSet(3));
f.instruction(&Instruction::I32Const(1));
f.instruction(&Instruction::LocalSet(4));
f.instruction(&Instruction::Block(wasm_encoder::BlockType::Empty));
f.instruction(&Instruction::Loop(wasm_encoder::BlockType::Empty));
f.instruction(&Instruction::LocalGet(3));
f.instruction(&Instruction::I32Eqz);
f.instruction(&Instruction::BrIf(1));
f.instruction(&Instruction::LocalGet(4));
f.instruction(&Instruction::I32Eqz);
f.instruction(&Instruction::If(wasm_encoder::BlockType::Empty));
f.instruction(&Instruction::LocalGet(2));
f.instruction(&Instruction::LocalGet(5));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::LocalSet(2));
f.instruction(&Instruction::End);
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::LocalSet(4));
f.instruction(&Instruction::LocalGet(3));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::Call(rt.obj_field));
f.instruction(&Instruction::I32WrapI64);
f.instruction(&Instruction::LocalSet(6));
f.instruction(&Instruction::LocalGet(2));
f.instruction(&Instruction::LocalGet(6));
f.instruction(&Instruction::I64Load(wasm_encoder::MemArg {
offset: 0,
align: 3,
memory_index: 0,
}));
f.instruction(&Instruction::I64Const(0xFFFFFFFF));
f.instruction(&Instruction::I64And);
f.instruction(&Instruction::I32WrapI64);
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::LocalSet(2));
f.instruction(&Instruction::LocalGet(3));
f.instruction(&Instruction::I32Const(1));
f.instruction(&Instruction::Call(rt.obj_field_i32));
f.instruction(&Instruction::LocalSet(3));
f.instruction(&Instruction::Br(0));
f.instruction(&Instruction::End);
f.instruction(&Instruction::End);
emit_alloc_string(&mut f, rt, 2, 8);
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::LocalSet(9));
f.instruction(&Instruction::LocalGet(0));
f.instruction(&Instruction::LocalSet(3));
f.instruction(&Instruction::I32Const(1));
f.instruction(&Instruction::LocalSet(4));
f.instruction(&Instruction::Block(wasm_encoder::BlockType::Empty));
f.instruction(&Instruction::Loop(wasm_encoder::BlockType::Empty));
f.instruction(&Instruction::LocalGet(3));
f.instruction(&Instruction::I32Eqz);
f.instruction(&Instruction::BrIf(1));
f.instruction(&Instruction::LocalGet(4));
f.instruction(&Instruction::I32Eqz);
f.instruction(&Instruction::If(wasm_encoder::BlockType::Empty));
f.instruction(&Instruction::LocalGet(8));
f.instruction(&Instruction::I32Const(8));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::LocalGet(9));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::LocalGet(1));
f.instruction(&Instruction::I32Const(8));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::LocalGet(5));
f.instruction(&Instruction::MemoryCopy {
src_mem: 0,
dst_mem: 0,
});
f.instruction(&Instruction::LocalGet(9));
f.instruction(&Instruction::LocalGet(5));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::LocalSet(9));
f.instruction(&Instruction::End);
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::LocalSet(4));
f.instruction(&Instruction::LocalGet(3));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::Call(rt.obj_field));
f.instruction(&Instruction::I32WrapI64);
f.instruction(&Instruction::LocalSet(6));
f.instruction(&Instruction::LocalGet(6));
f.instruction(&Instruction::I64Load(wasm_encoder::MemArg {
offset: 0,
align: 3,
memory_index: 0,
}));
f.instruction(&Instruction::I64Const(0xFFFFFFFF));
f.instruction(&Instruction::I64And);
f.instruction(&Instruction::I32WrapI64);
f.instruction(&Instruction::LocalSet(7));
f.instruction(&Instruction::LocalGet(8));
f.instruction(&Instruction::I32Const(8));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::LocalGet(9));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::LocalGet(6));
f.instruction(&Instruction::I32Const(8));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::LocalGet(7));
f.instruction(&Instruction::MemoryCopy {
src_mem: 0,
dst_mem: 0,
});
f.instruction(&Instruction::LocalGet(9));
f.instruction(&Instruction::LocalGet(7));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::LocalSet(9));
f.instruction(&Instruction::LocalGet(3));
f.instruction(&Instruction::I32Const(1));
f.instruction(&Instruction::Call(rt.obj_field_i32));
f.instruction(&Instruction::LocalSet(3));
f.instruction(&Instruction::Br(0));
f.instruction(&Instruction::End);
f.instruction(&Instruction::End);
f.instruction(&Instruction::LocalGet(8));
f.instruction(&Instruction::End);
f
}
pub fn emit_str_replace(rt: &RuntimeFuncIndices) -> Function {
let mut f = Function::new(vec![(1, ValType::I32)]);
f.instruction(&Instruction::LocalGet(2));
f.instruction(&Instruction::LocalSet(3));
f.instruction(&Instruction::LocalGet(0));
f.instruction(&Instruction::LocalGet(1));
f.instruction(&Instruction::Call(rt.str_split));
f.instruction(&Instruction::LocalGet(3));
f.instruction(&Instruction::Call(rt.str_join));
f.instruction(&Instruction::End);
f
}
pub fn emit_str_to_lower(rt: &RuntimeFuncIndices) -> Function {
emit_str_ascii_case(rt, false)
}
pub fn emit_str_to_upper(rt: &RuntimeFuncIndices) -> Function {
emit_str_ascii_case(rt, true)
}
pub fn emit_int_from_str(rt: &RuntimeFuncIndices) -> Function {
let mut f = Function::new(vec![
(1, ValType::I32),
(1, ValType::I64),
(1, ValType::I32),
(1, ValType::I32),
]);
f.instruction(&Instruction::LocalGet(0));
f.instruction(&Instruction::I64Load(wasm_encoder::MemArg {
offset: 0,
align: 3,
memory_index: 0,
}));
f.instruction(&Instruction::I64Const(0xFFFFFFFF));
f.instruction(&Instruction::I64And);
f.instruction(&Instruction::I32WrapI64);
f.instruction(&Instruction::LocalSet(1));
f.instruction(&Instruction::I64Const(0));
f.instruction(&Instruction::LocalSet(2));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::LocalSet(3));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::LocalSet(4));
f.instruction(&Instruction::LocalGet(1));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::I32GtS);
f.instruction(&Instruction::If(wasm_encoder::BlockType::Empty));
f.instruction(&Instruction::LocalGet(0));
f.instruction(&Instruction::I32Load8U(wasm_encoder::MemArg {
offset: 8,
align: 0,
memory_index: 0,
}));
f.instruction(&Instruction::I32Const(b'-' as i32));
f.instruction(&Instruction::I32Eq);
f.instruction(&Instruction::If(wasm_encoder::BlockType::Empty));
f.instruction(&Instruction::I32Const(1));
f.instruction(&Instruction::LocalSet(4));
f.instruction(&Instruction::I32Const(1));
f.instruction(&Instruction::LocalSet(3));
f.instruction(&Instruction::End);
f.instruction(&Instruction::End);
f.instruction(&Instruction::Block(wasm_encoder::BlockType::Empty));
f.instruction(&Instruction::Loop(wasm_encoder::BlockType::Empty));
f.instruction(&Instruction::LocalGet(3));
f.instruction(&Instruction::LocalGet(1));
f.instruction(&Instruction::I32GeU);
f.instruction(&Instruction::BrIf(1));
f.instruction(&Instruction::LocalGet(2));
f.instruction(&Instruction::I64Const(10));
f.instruction(&Instruction::I64Mul);
f.instruction(&Instruction::LocalGet(0));
f.instruction(&Instruction::LocalGet(3));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::I32Load8U(wasm_encoder::MemArg {
offset: 8,
align: 0,
memory_index: 0,
}));
f.instruction(&Instruction::I32Const(b'0' as i32));
f.instruction(&Instruction::I32Sub);
f.instruction(&Instruction::I64ExtendI32U);
f.instruction(&Instruction::I64Add);
f.instruction(&Instruction::LocalSet(2));
f.instruction(&Instruction::LocalGet(3));
f.instruction(&Instruction::I32Const(1));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::LocalSet(3));
f.instruction(&Instruction::Br(0));
f.instruction(&Instruction::End);
f.instruction(&Instruction::End);
f.instruction(&Instruction::LocalGet(4));
f.instruction(&Instruction::If(wasm_encoder::BlockType::Empty));
f.instruction(&Instruction::I64Const(0));
f.instruction(&Instruction::LocalGet(2));
f.instruction(&Instruction::I64Sub);
f.instruction(&Instruction::LocalSet(2));
f.instruction(&Instruction::End);
f.instruction(&Instruction::I32Const(WRAP_OK as i32));
f.instruction(&Instruction::LocalGet(2));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::Call(rt.wrap));
f.instruction(&Instruction::End);
f
}
pub fn emit_float_from_str(rt: &RuntimeFuncIndices) -> Function {
let mut f = Function::new(vec![
(11, ValType::I32), (2, ValType::F64), ]);
f.instruction(&Instruction::LocalGet(0));
f.instruction(&Instruction::I64Load(wasm_encoder::MemArg {
offset: 0,
align: 3,
memory_index: 0,
}));
f.instruction(&Instruction::I64Const(0xFFFFFFFF));
f.instruction(&Instruction::I64And);
f.instruction(&Instruction::I32WrapI64);
f.instruction(&Instruction::LocalSet(1));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::LocalSet(2));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::LocalSet(3));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::LocalSet(4));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::LocalSet(5));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::LocalSet(8));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::LocalSet(9));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::LocalSet(10));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::LocalSet(11));
f.instruction(&Instruction::F64Const(0.0));
f.instruction(&Instruction::LocalSet(12));
f.instruction(&Instruction::F64Const(1.0));
f.instruction(&Instruction::LocalSet(13));
f.instruction(&Instruction::LocalGet(1));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::I32GtS);
f.instruction(&Instruction::If(wasm_encoder::BlockType::Empty));
f.instruction(&Instruction::LocalGet(0));
f.instruction(&Instruction::I32Load8U(wasm_encoder::MemArg {
offset: 8,
align: 0,
memory_index: 0,
}));
f.instruction(&Instruction::I32Const(b'-' as i32));
f.instruction(&Instruction::I32Eq);
f.instruction(&Instruction::If(wasm_encoder::BlockType::Empty));
f.instruction(&Instruction::I32Const(1));
f.instruction(&Instruction::LocalSet(3));
f.instruction(&Instruction::I32Const(1));
f.instruction(&Instruction::LocalSet(2));
f.instruction(&Instruction::End);
f.instruction(&Instruction::End);
f.instruction(&Instruction::Block(wasm_encoder::BlockType::Empty));
f.instruction(&Instruction::Loop(wasm_encoder::BlockType::Empty));
f.instruction(&Instruction::LocalGet(2));
f.instruction(&Instruction::LocalGet(1));
f.instruction(&Instruction::I32GeU);
f.instruction(&Instruction::BrIf(1));
f.instruction(&Instruction::LocalGet(0));
f.instruction(&Instruction::LocalGet(2));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::I32Load8U(wasm_encoder::MemArg {
offset: 8,
align: 0,
memory_index: 0,
}));
f.instruction(&Instruction::LocalSet(6));
f.instruction(&Instruction::LocalGet(8));
f.instruction(&Instruction::I32Const(1));
f.instruction(&Instruction::I32Eq);
f.instruction(&Instruction::LocalGet(6));
f.instruction(&Instruction::I32Const(b'+' as i32));
f.instruction(&Instruction::I32Eq);
f.instruction(&Instruction::I32And);
f.instruction(&Instruction::If(wasm_encoder::BlockType::Empty));
f.instruction(&Instruction::I32Const(2));
f.instruction(&Instruction::LocalSet(8));
f.instruction(&Instruction::LocalGet(2));
f.instruction(&Instruction::I32Const(1));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::LocalSet(2));
f.instruction(&Instruction::Br(1));
f.instruction(&Instruction::End);
f.instruction(&Instruction::LocalGet(8));
f.instruction(&Instruction::I32Const(1));
f.instruction(&Instruction::I32Eq);
f.instruction(&Instruction::LocalGet(6));
f.instruction(&Instruction::I32Const(b'-' as i32));
f.instruction(&Instruction::I32Eq);
f.instruction(&Instruction::I32And);
f.instruction(&Instruction::If(wasm_encoder::BlockType::Empty));
f.instruction(&Instruction::I32Const(1));
f.instruction(&Instruction::LocalSet(9));
f.instruction(&Instruction::I32Const(2));
f.instruction(&Instruction::LocalSet(8));
f.instruction(&Instruction::LocalGet(2));
f.instruction(&Instruction::I32Const(1));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::LocalSet(2));
f.instruction(&Instruction::Br(1));
f.instruction(&Instruction::End);
f.instruction(&Instruction::LocalGet(8));
f.instruction(&Instruction::If(wasm_encoder::BlockType::Empty));
f.instruction(&Instruction::LocalGet(6));
f.instruction(&Instruction::I32Const(b'0' as i32));
f.instruction(&Instruction::I32LtU);
f.instruction(&Instruction::If(wasm_encoder::BlockType::Empty));
emit_float_parse_error(&mut f, rt);
f.instruction(&Instruction::End);
f.instruction(&Instruction::LocalGet(6));
f.instruction(&Instruction::I32Const(b'9' as i32));
f.instruction(&Instruction::I32GtU);
f.instruction(&Instruction::If(wasm_encoder::BlockType::Empty));
emit_float_parse_error(&mut f, rt);
f.instruction(&Instruction::End);
f.instruction(&Instruction::I32Const(1));
f.instruction(&Instruction::LocalSet(10));
f.instruction(&Instruction::I32Const(2));
f.instruction(&Instruction::LocalSet(8));
f.instruction(&Instruction::LocalGet(6));
f.instruction(&Instruction::I32Const(b'0' as i32));
f.instruction(&Instruction::I32Sub);
f.instruction(&Instruction::LocalSet(7));
f.instruction(&Instruction::LocalGet(11));
f.instruction(&Instruction::I32Const(10));
f.instruction(&Instruction::I32Mul);
f.instruction(&Instruction::LocalGet(7));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::LocalSet(11));
f.instruction(&Instruction::LocalGet(2));
f.instruction(&Instruction::I32Const(1));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::LocalSet(2));
f.instruction(&Instruction::Br(1));
f.instruction(&Instruction::End);
f.instruction(&Instruction::LocalGet(6));
f.instruction(&Instruction::I32Const(b'.' as i32));
f.instruction(&Instruction::I32Eq);
f.instruction(&Instruction::If(wasm_encoder::BlockType::Empty));
f.instruction(&Instruction::LocalGet(4));
f.instruction(&Instruction::If(wasm_encoder::BlockType::Empty));
emit_float_parse_error(&mut f, rt);
f.instruction(&Instruction::End);
f.instruction(&Instruction::I32Const(1));
f.instruction(&Instruction::LocalSet(4));
f.instruction(&Instruction::LocalGet(2));
f.instruction(&Instruction::I32Const(1));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::LocalSet(2));
f.instruction(&Instruction::Br(1));
f.instruction(&Instruction::End);
f.instruction(&Instruction::LocalGet(6));
f.instruction(&Instruction::I32Const(b'e' as i32));
f.instruction(&Instruction::I32Eq);
f.instruction(&Instruction::LocalGet(6));
f.instruction(&Instruction::I32Const(b'E' as i32));
f.instruction(&Instruction::I32Eq);
f.instruction(&Instruction::I32Or);
f.instruction(&Instruction::If(wasm_encoder::BlockType::Empty));
f.instruction(&Instruction::LocalGet(5));
f.instruction(&Instruction::I32Eqz);
f.instruction(&Instruction::If(wasm_encoder::BlockType::Empty));
emit_float_parse_error(&mut f, rt);
f.instruction(&Instruction::End);
f.instruction(&Instruction::I32Const(1));
f.instruction(&Instruction::LocalSet(8));
f.instruction(&Instruction::LocalGet(2));
f.instruction(&Instruction::I32Const(1));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::LocalSet(2));
f.instruction(&Instruction::Br(1));
f.instruction(&Instruction::End);
f.instruction(&Instruction::LocalGet(6));
f.instruction(&Instruction::I32Const(b'0' as i32));
f.instruction(&Instruction::I32LtU);
f.instruction(&Instruction::If(wasm_encoder::BlockType::Empty));
emit_float_parse_error(&mut f, rt);
f.instruction(&Instruction::End);
f.instruction(&Instruction::LocalGet(6));
f.instruction(&Instruction::I32Const(b'9' as i32));
f.instruction(&Instruction::I32GtU);
f.instruction(&Instruction::If(wasm_encoder::BlockType::Empty));
emit_float_parse_error(&mut f, rt);
f.instruction(&Instruction::End);
f.instruction(&Instruction::I32Const(1));
f.instruction(&Instruction::LocalSet(5));
f.instruction(&Instruction::LocalGet(6));
f.instruction(&Instruction::I32Const(b'0' as i32));
f.instruction(&Instruction::I32Sub);
f.instruction(&Instruction::LocalSet(7));
f.instruction(&Instruction::LocalGet(4));
f.instruction(&Instruction::If(wasm_encoder::BlockType::Empty));
f.instruction(&Instruction::LocalGet(13));
f.instruction(&Instruction::F64Const(10.0));
f.instruction(&Instruction::F64Mul);
f.instruction(&Instruction::LocalSet(13));
f.instruction(&Instruction::LocalGet(12));
f.instruction(&Instruction::LocalGet(7));
f.instruction(&Instruction::F64ConvertI32U);
f.instruction(&Instruction::LocalGet(13));
f.instruction(&Instruction::F64Div);
f.instruction(&Instruction::F64Add);
f.instruction(&Instruction::LocalSet(12));
f.instruction(&Instruction::Else);
f.instruction(&Instruction::LocalGet(12));
f.instruction(&Instruction::F64Const(10.0));
f.instruction(&Instruction::F64Mul);
f.instruction(&Instruction::LocalGet(7));
f.instruction(&Instruction::F64ConvertI32U);
f.instruction(&Instruction::F64Add);
f.instruction(&Instruction::LocalSet(12));
f.instruction(&Instruction::End);
f.instruction(&Instruction::LocalGet(2));
f.instruction(&Instruction::I32Const(1));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::LocalSet(2));
f.instruction(&Instruction::Br(0));
f.instruction(&Instruction::End);
f.instruction(&Instruction::End);
f.instruction(&Instruction::LocalGet(5));
f.instruction(&Instruction::I32Eqz);
f.instruction(&Instruction::If(wasm_encoder::BlockType::Empty));
emit_float_parse_error(&mut f, rt);
f.instruction(&Instruction::End);
f.instruction(&Instruction::LocalGet(8));
f.instruction(&Instruction::I32Const(1));
f.instruction(&Instruction::I32Eq);
f.instruction(&Instruction::If(wasm_encoder::BlockType::Empty));
emit_float_parse_error(&mut f, rt);
f.instruction(&Instruction::End);
f.instruction(&Instruction::LocalGet(8));
f.instruction(&Instruction::I32Const(2));
f.instruction(&Instruction::I32Eq);
f.instruction(&Instruction::LocalGet(10));
f.instruction(&Instruction::I32Eqz);
f.instruction(&Instruction::I32And);
f.instruction(&Instruction::If(wasm_encoder::BlockType::Empty));
emit_float_parse_error(&mut f, rt);
f.instruction(&Instruction::End);
f.instruction(&Instruction::Block(wasm_encoder::BlockType::Empty));
f.instruction(&Instruction::Loop(wasm_encoder::BlockType::Empty));
f.instruction(&Instruction::LocalGet(11));
f.instruction(&Instruction::I32Eqz);
f.instruction(&Instruction::BrIf(1));
f.instruction(&Instruction::LocalGet(9));
f.instruction(&Instruction::If(wasm_encoder::BlockType::Empty));
f.instruction(&Instruction::LocalGet(12));
f.instruction(&Instruction::F64Const(10.0));
f.instruction(&Instruction::F64Div);
f.instruction(&Instruction::LocalSet(12));
f.instruction(&Instruction::Else);
f.instruction(&Instruction::LocalGet(12));
f.instruction(&Instruction::F64Const(10.0));
f.instruction(&Instruction::F64Mul);
f.instruction(&Instruction::LocalSet(12));
f.instruction(&Instruction::End);
f.instruction(&Instruction::LocalGet(11));
f.instruction(&Instruction::I32Const(1));
f.instruction(&Instruction::I32Sub);
f.instruction(&Instruction::LocalSet(11));
f.instruction(&Instruction::Br(0));
f.instruction(&Instruction::End);
f.instruction(&Instruction::End);
f.instruction(&Instruction::LocalGet(3));
f.instruction(&Instruction::If(wasm_encoder::BlockType::Empty));
f.instruction(&Instruction::F64Const(0.0));
f.instruction(&Instruction::LocalGet(12));
f.instruction(&Instruction::F64Sub);
f.instruction(&Instruction::LocalSet(12));
f.instruction(&Instruction::End);
f.instruction(&Instruction::I32Const(WRAP_OK as i32));
f.instruction(&Instruction::LocalGet(12));
f.instruction(&Instruction::Call(rt.wrap_f64));
f.instruction(&Instruction::End);
f
}
fn emit_load_string_byte_len(f: &mut Function, str_local: u32, len_local: u32) {
f.instruction(&Instruction::LocalGet(str_local));
f.instruction(&Instruction::I64Load(wasm_encoder::MemArg {
offset: 0,
align: 3,
memory_index: 0,
}));
f.instruction(&Instruction::I64Const(0xFFFFFFFF));
f.instruction(&Instruction::I64And);
f.instruction(&Instruction::I32WrapI64);
f.instruction(&Instruction::LocalSet(len_local));
}
fn emit_set_utf8_char_width(f: &mut Function, lead_local: u32, width_local: u32) {
f.instruction(&Instruction::LocalGet(lead_local));
f.instruction(&Instruction::I32Const(0x80));
f.instruction(&Instruction::I32LtU);
f.instruction(&Instruction::If(wasm_encoder::BlockType::Empty));
f.instruction(&Instruction::I32Const(1));
f.instruction(&Instruction::LocalSet(width_local));
f.instruction(&Instruction::Else);
f.instruction(&Instruction::LocalGet(lead_local));
f.instruction(&Instruction::I32Const(0xE0));
f.instruction(&Instruction::I32LtU);
f.instruction(&Instruction::If(wasm_encoder::BlockType::Empty));
f.instruction(&Instruction::I32Const(2));
f.instruction(&Instruction::LocalSet(width_local));
f.instruction(&Instruction::Else);
f.instruction(&Instruction::LocalGet(lead_local));
f.instruction(&Instruction::I32Const(0xF0));
f.instruction(&Instruction::I32LtU);
f.instruction(&Instruction::If(wasm_encoder::BlockType::Empty));
f.instruction(&Instruction::I32Const(3));
f.instruction(&Instruction::LocalSet(width_local));
f.instruction(&Instruction::Else);
f.instruction(&Instruction::I32Const(4));
f.instruction(&Instruction::LocalSet(width_local));
f.instruction(&Instruction::End);
f.instruction(&Instruction::End);
f.instruction(&Instruction::End);
}
fn emit_push_hex_char(f: &mut Function, nibble_local: u32) {
f.instruction(&Instruction::LocalGet(nibble_local));
f.instruction(&Instruction::I32Const(10));
f.instruction(&Instruction::I32LtU);
f.instruction(&Instruction::If(wasm_encoder::BlockType::Result(
ValType::I32,
)));
f.instruction(&Instruction::LocalGet(nibble_local));
f.instruction(&Instruction::I32Const(b'0' as i32));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::Else);
f.instruction(&Instruction::LocalGet(nibble_local));
f.instruction(&Instruction::I32Const(10));
f.instruction(&Instruction::I32Sub);
f.instruction(&Instruction::I32Const(b'a' as i32));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::End);
}
fn emit_set_hex_nibble(
f: &mut Function,
rt: &RuntimeFuncIndices,
ch_local: u32,
value_local: u32,
err_ptr_local: u32,
) {
f.instruction(&Instruction::LocalGet(ch_local));
f.instruction(&Instruction::I32Const(b'0' as i32));
f.instruction(&Instruction::I32GeU);
f.instruction(&Instruction::LocalGet(ch_local));
f.instruction(&Instruction::I32Const(b'9' as i32));
f.instruction(&Instruction::I32LeU);
f.instruction(&Instruction::I32And);
f.instruction(&Instruction::If(wasm_encoder::BlockType::Empty));
f.instruction(&Instruction::LocalGet(ch_local));
f.instruction(&Instruction::I32Const(b'0' as i32));
f.instruction(&Instruction::I32Sub);
f.instruction(&Instruction::LocalSet(value_local));
f.instruction(&Instruction::Else);
f.instruction(&Instruction::LocalGet(ch_local));
f.instruction(&Instruction::I32Const(b'a' as i32));
f.instruction(&Instruction::I32GeU);
f.instruction(&Instruction::LocalGet(ch_local));
f.instruction(&Instruction::I32Const(b'f' as i32));
f.instruction(&Instruction::I32LeU);
f.instruction(&Instruction::I32And);
f.instruction(&Instruction::If(wasm_encoder::BlockType::Empty));
f.instruction(&Instruction::LocalGet(ch_local));
f.instruction(&Instruction::I32Const(b'a' as i32));
f.instruction(&Instruction::I32Sub);
f.instruction(&Instruction::I32Const(10));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::LocalSet(value_local));
f.instruction(&Instruction::Else);
f.instruction(&Instruction::LocalGet(ch_local));
f.instruction(&Instruction::I32Const(b'A' as i32));
f.instruction(&Instruction::I32GeU);
f.instruction(&Instruction::LocalGet(ch_local));
f.instruction(&Instruction::I32Const(b'F' as i32));
f.instruction(&Instruction::I32LeU);
f.instruction(&Instruction::I32And);
f.instruction(&Instruction::If(wasm_encoder::BlockType::Empty));
f.instruction(&Instruction::LocalGet(ch_local));
f.instruction(&Instruction::I32Const(b'A' as i32));
f.instruction(&Instruction::I32Sub);
f.instruction(&Instruction::I32Const(10));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::LocalSet(value_local));
f.instruction(&Instruction::Else);
emit_return_err_empty_string(f, rt, err_ptr_local);
f.instruction(&Instruction::End);
f.instruction(&Instruction::End);
f.instruction(&Instruction::End);
}
fn emit_return_err_empty_string(f: &mut Function, rt: &RuntimeFuncIndices, ptr_local: u32) {
f.instruction(&Instruction::I32Const(8));
f.instruction(&Instruction::Call(rt.alloc));
f.instruction(&Instruction::LocalSet(ptr_local));
f.instruction(&Instruction::LocalGet(ptr_local));
f.instruction(&Instruction::I64Const(
(OBJ_STRING << HDR_KIND_SHIFT) as i64,
));
f.instruction(&Instruction::I64Store(wasm_encoder::MemArg {
offset: 0,
align: 3,
memory_index: 0,
}));
f.instruction(&Instruction::I32Const(WRAP_ERR as i32));
f.instruction(&Instruction::LocalGet(ptr_local));
f.instruction(&Instruction::I32Const(1));
f.instruction(&Instruction::Call(rt.wrap_i32));
f.instruction(&Instruction::Return);
}
fn emit_float_parse_error(f: &mut Function, rt: &RuntimeFuncIndices) {
f.instruction(&Instruction::I32Const(WRAP_ERR as i32));
f.instruction(&Instruction::LocalGet(0));
f.instruction(&Instruction::I32Const(1));
f.instruction(&Instruction::Call(rt.wrap_i32));
f.instruction(&Instruction::Return);
}
fn emit_is_whitespace(f: &mut Function, ch_local: u32) {
f.instruction(&Instruction::LocalGet(ch_local));
f.instruction(&Instruction::I32Const(b' ' as i32));
f.instruction(&Instruction::I32Eq);
f.instruction(&Instruction::LocalGet(ch_local));
f.instruction(&Instruction::I32Const(b'\t' as i32));
f.instruction(&Instruction::I32Eq);
f.instruction(&Instruction::I32Or);
f.instruction(&Instruction::LocalGet(ch_local));
f.instruction(&Instruction::I32Const(b'\n' as i32));
f.instruction(&Instruction::I32Eq);
f.instruction(&Instruction::I32Or);
f.instruction(&Instruction::LocalGet(ch_local));
f.instruction(&Instruction::I32Const(b'\r' as i32));
f.instruction(&Instruction::I32Eq);
f.instruction(&Instruction::I32Or);
}
fn emit_copy_string_range(
f: &mut Function,
rt: &RuntimeFuncIndices,
src_local: u32,
start_local: u32,
len_local: u32,
ptr_local: u32,
) {
emit_alloc_string(f, rt, len_local, ptr_local);
f.instruction(&Instruction::LocalGet(ptr_local));
f.instruction(&Instruction::I32Const(8));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::LocalGet(src_local));
f.instruction(&Instruction::I32Const(8));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::LocalGet(start_local));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::LocalGet(len_local));
f.instruction(&Instruction::MemoryCopy {
src_mem: 0,
dst_mem: 0,
});
}
fn emit_alloc_string(f: &mut Function, rt: &RuntimeFuncIndices, len_local: u32, ptr_local: u32) {
f.instruction(&Instruction::I32Const(8));
f.instruction(&Instruction::LocalGet(len_local));
f.instruction(&Instruction::I32Const(7));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::I32Const(-8i32));
f.instruction(&Instruction::I32And);
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::Call(rt.alloc));
f.instruction(&Instruction::LocalSet(ptr_local));
f.instruction(&Instruction::LocalGet(ptr_local));
f.instruction(&Instruction::I64Const(
(OBJ_STRING << HDR_KIND_SHIFT) as i64,
));
f.instruction(&Instruction::LocalGet(len_local));
f.instruction(&Instruction::I64ExtendI32U);
f.instruction(&Instruction::I64Or);
f.instruction(&Instruction::I64Store(wasm_encoder::MemArg {
offset: 0,
align: 3,
memory_index: 0,
}));
}
fn emit_str_ascii_case(rt: &RuntimeFuncIndices, upper: bool) -> Function {
let mut f = Function::new(vec![(4, ValType::I32)]);
emit_load_string_byte_len(&mut f, 0, 1);
emit_alloc_string(&mut f, rt, 1, 3);
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::LocalSet(2));
f.instruction(&Instruction::Block(wasm_encoder::BlockType::Empty));
f.instruction(&Instruction::Loop(wasm_encoder::BlockType::Empty));
f.instruction(&Instruction::LocalGet(2));
f.instruction(&Instruction::LocalGet(1));
f.instruction(&Instruction::I32GeU);
f.instruction(&Instruction::BrIf(1));
f.instruction(&Instruction::LocalGet(0));
f.instruction(&Instruction::LocalGet(2));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::I32Load8U(wasm_encoder::MemArg {
offset: 8,
align: 0,
memory_index: 0,
}));
f.instruction(&Instruction::LocalSet(4));
if upper {
f.instruction(&Instruction::LocalGet(4));
f.instruction(&Instruction::I32Const(b'a' as i32));
f.instruction(&Instruction::I32GeU);
f.instruction(&Instruction::LocalGet(4));
f.instruction(&Instruction::I32Const(b'z' as i32));
f.instruction(&Instruction::I32LeU);
f.instruction(&Instruction::I32And);
f.instruction(&Instruction::If(wasm_encoder::BlockType::Empty));
f.instruction(&Instruction::LocalGet(4));
f.instruction(&Instruction::I32Const(32));
f.instruction(&Instruction::I32Sub);
f.instruction(&Instruction::LocalSet(4));
f.instruction(&Instruction::End);
} else {
f.instruction(&Instruction::LocalGet(4));
f.instruction(&Instruction::I32Const(b'A' as i32));
f.instruction(&Instruction::I32GeU);
f.instruction(&Instruction::LocalGet(4));
f.instruction(&Instruction::I32Const(b'Z' as i32));
f.instruction(&Instruction::I32LeU);
f.instruction(&Instruction::I32And);
f.instruction(&Instruction::If(wasm_encoder::BlockType::Empty));
f.instruction(&Instruction::LocalGet(4));
f.instruction(&Instruction::I32Const(32));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::LocalSet(4));
f.instruction(&Instruction::End);
}
f.instruction(&Instruction::LocalGet(3));
f.instruction(&Instruction::LocalGet(2));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::LocalGet(4));
f.instruction(&Instruction::I32Store8(wasm_encoder::MemArg {
offset: 8,
align: 0,
memory_index: 0,
}));
f.instruction(&Instruction::LocalGet(2));
f.instruction(&Instruction::I32Const(1));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::LocalSet(2));
f.instruction(&Instruction::Br(0));
f.instruction(&Instruction::End);
f.instruction(&Instruction::End);
f.instruction(&Instruction::LocalGet(3));
f.instruction(&Instruction::End);
f
}