use wasm_encoder::{Function, Instruction, ValType};
use super::super::value::*;
use super::RuntimeFuncIndices;
pub(super) fn emit_map_get(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::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::I32Eqz);
f.instruction(&Instruction::BrIf(1)); f.instruction(&Instruction::LocalGet(2));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::Call(rt.obj_field)); f.instruction(&Instruction::I32WrapI64);
f.instruction(&Instruction::LocalSet(3)); f.instruction(&Instruction::LocalGet(3));
f.instruction(&Instruction::Call(rt.obj_meta));
f.instruction(&Instruction::LocalSet(5));
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(4));
f.instruction(&Instruction::LocalGet(4));
f.instruction(&Instruction::LocalGet(1));
f.instruction(&Instruction::Call(rt.str_eq));
f.instruction(&Instruction::If(wasm_encoder::BlockType::Empty));
f.instruction(&Instruction::I32Const(WRAP_SOME as i32));
f.instruction(&Instruction::LocalGet(3));
f.instruction(&Instruction::I32Const(1));
f.instruction(&Instruction::Call(rt.obj_field)); f.instruction(&Instruction::LocalGet(5));
f.instruction(&Instruction::I32Const(1));
f.instruction(&Instruction::I32ShrU);
f.instruction(&Instruction::I32Const(1));
f.instruction(&Instruction::I32And);
f.instruction(&Instruction::Call(rt.wrap)); f.instruction(&Instruction::Return);
f.instruction(&Instruction::End);
f.instruction(&Instruction::LocalGet(2));
f.instruction(&Instruction::I32Const(1));
f.instruction(&Instruction::Call(rt.obj_field_i32));
f.instruction(&Instruction::LocalSet(2));
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(super) fn emit_map_set(rt: &RuntimeFuncIndices) -> Function {
let mut f = Function::new(vec![(8, ValType::I32)]);
f.instruction(&Instruction::I32Const(24));
f.instruction(&Instruction::Call(rt.alloc));
f.instruction(&Instruction::LocalSet(4));
f.instruction(&Instruction::LocalGet(4));
f.instruction(&Instruction::I64Const((OBJ_TUPLE << HDR_KIND_SHIFT) as i64));
f.instruction(&Instruction::I64Const(1));
f.instruction(&Instruction::LocalGet(3));
f.instruction(&Instruction::I64ExtendI32U);
f.instruction(&Instruction::I64Const(1));
f.instruction(&Instruction::I64Shl);
f.instruction(&Instruction::I64Or);
f.instruction(&Instruction::I64Const(HDR_META_SHIFT as i64));
f.instruction(&Instruction::I64Shl);
f.instruction(&Instruction::I64Or);
f.instruction(&Instruction::I64Const(2));
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::LocalGet(1));
f.instruction(&Instruction::I64ExtendI32U);
f.instruction(&Instruction::I64Store(wasm_encoder::MemArg {
offset: 8,
align: 3,
memory_index: 0,
}));
f.instruction(&Instruction::LocalGet(4));
f.instruction(&Instruction::LocalGet(2));
f.instruction(&Instruction::I64Store(wasm_encoder::MemArg {
offset: 16,
align: 3,
memory_index: 0,
}));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::LocalSet(11));
f.instruction(&Instruction::LocalGet(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(5));
f.instruction(&Instruction::I32Eqz);
f.instruction(&Instruction::BrIf(1)); f.instruction(&Instruction::LocalGet(5));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::Call(rt.obj_field));
f.instruction(&Instruction::I32WrapI64);
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::Call(rt.obj_field));
f.instruction(&Instruction::I32WrapI64);
f.instruction(&Instruction::LocalGet(1));
f.instruction(&Instruction::Call(rt.str_eq));
f.instruction(&Instruction::If(wasm_encoder::BlockType::Empty));
f.instruction(&Instruction::I32Const(1));
f.instruction(&Instruction::LocalSet(11));
f.instruction(&Instruction::Br(2)); f.instruction(&Instruction::End);
f.instruction(&Instruction::LocalGet(5));
f.instruction(&Instruction::I32Const(1));
f.instruction(&Instruction::Call(rt.obj_field_i32));
f.instruction(&Instruction::LocalSet(5));
f.instruction(&Instruction::Br(0));
f.instruction(&Instruction::End); f.instruction(&Instruction::End);
f.instruction(&Instruction::LocalGet(11));
f.instruction(&Instruction::I32Eqz);
f.instruction(&Instruction::If(wasm_encoder::BlockType::Result(
ValType::I32,
)));
f.instruction(&Instruction::I32Const(24));
f.instruction(&Instruction::Call(rt.alloc));
f.instruction(&Instruction::LocalSet(10));
f.instruction(&Instruction::LocalGet(10));
f.instruction(&Instruction::I64Const(
make_header(OBJ_MAP_ENTRY, 0, 0, 2) as i64
));
f.instruction(&Instruction::I64Store(wasm_encoder::MemArg {
offset: 0,
align: 3,
memory_index: 0,
}));
f.instruction(&Instruction::LocalGet(10));
f.instruction(&Instruction::LocalGet(4));
f.instruction(&Instruction::I64ExtendI32U);
f.instruction(&Instruction::I64Store(wasm_encoder::MemArg {
offset: 8,
align: 3,
memory_index: 0,
}));
f.instruction(&Instruction::LocalGet(10));
f.instruction(&Instruction::LocalGet(0)); f.instruction(&Instruction::I64ExtendI32S);
f.instruction(&Instruction::I64Store(wasm_encoder::MemArg {
offset: 16,
align: 3,
memory_index: 0,
}));
f.instruction(&Instruction::LocalGet(10));
f.instruction(&Instruction::Else);
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::LocalSet(8));
f.instruction(&Instruction::LocalGet(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(5));
f.instruction(&Instruction::I32Eqz);
f.instruction(&Instruction::BrIf(1));
f.instruction(&Instruction::LocalGet(5));
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::I32Const(0));
f.instruction(&Instruction::Call(rt.obj_field));
f.instruction(&Instruction::I32WrapI64);
f.instruction(&Instruction::LocalSet(7));
f.instruction(&Instruction::LocalGet(7));
f.instruction(&Instruction::LocalGet(1));
f.instruction(&Instruction::Call(rt.str_eq));
f.instruction(&Instruction::If(wasm_encoder::BlockType::Empty));
f.instruction(&Instruction::Else);
f.instruction(&Instruction::LocalGet(6));
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::End);
f.instruction(&Instruction::LocalGet(5));
f.instruction(&Instruction::I32Const(1));
f.instruction(&Instruction::Call(rt.obj_field_i32));
f.instruction(&Instruction::LocalSet(5));
f.instruction(&Instruction::Br(0));
f.instruction(&Instruction::End);
f.instruction(&Instruction::End);
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::LocalSet(9));
f.instruction(&Instruction::LocalGet(8));
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(5));
f.instruction(&Instruction::I32Eqz);
f.instruction(&Instruction::BrIf(1));
f.instruction(&Instruction::I32Const(24));
f.instruction(&Instruction::Call(rt.alloc));
f.instruction(&Instruction::LocalSet(10));
f.instruction(&Instruction::LocalGet(10));
f.instruction(&Instruction::I64Const(
make_header(OBJ_MAP_ENTRY, 0, 0, 2) as i64
));
f.instruction(&Instruction::I64Store(wasm_encoder::MemArg {
offset: 0,
align: 3,
memory_index: 0,
}));
f.instruction(&Instruction::LocalGet(10));
f.instruction(&Instruction::LocalGet(5));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::Call(rt.obj_field));
f.instruction(&Instruction::I64Store(wasm_encoder::MemArg {
offset: 8,
align: 3,
memory_index: 0,
}));
f.instruction(&Instruction::LocalGet(10));
f.instruction(&Instruction::LocalGet(9));
f.instruction(&Instruction::I64ExtendI32S);
f.instruction(&Instruction::I64Store(wasm_encoder::MemArg {
offset: 16,
align: 3,
memory_index: 0,
}));
f.instruction(&Instruction::LocalGet(10));
f.instruction(&Instruction::LocalSet(9));
f.instruction(&Instruction::LocalGet(5));
f.instruction(&Instruction::I32Const(1));
f.instruction(&Instruction::Call(rt.obj_field_i32));
f.instruction(&Instruction::LocalSet(5));
f.instruction(&Instruction::Br(0));
f.instruction(&Instruction::End);
f.instruction(&Instruction::End);
f.instruction(&Instruction::I32Const(24));
f.instruction(&Instruction::Call(rt.alloc));
f.instruction(&Instruction::LocalSet(10));
f.instruction(&Instruction::LocalGet(10));
f.instruction(&Instruction::I64Const(
make_header(OBJ_MAP_ENTRY, 0, 0, 2) as i64
));
f.instruction(&Instruction::I64Store(wasm_encoder::MemArg {
offset: 0,
align: 3,
memory_index: 0,
}));
f.instruction(&Instruction::LocalGet(10));
f.instruction(&Instruction::LocalGet(4));
f.instruction(&Instruction::I64ExtendI32U);
f.instruction(&Instruction::I64Store(wasm_encoder::MemArg {
offset: 8,
align: 3,
memory_index: 0,
}));
f.instruction(&Instruction::LocalGet(10));
f.instruction(&Instruction::LocalGet(9));
f.instruction(&Instruction::I64ExtendI32S);
f.instruction(&Instruction::I64Store(wasm_encoder::MemArg {
offset: 16,
align: 3,
memory_index: 0,
}));
f.instruction(&Instruction::LocalGet(10));
f.instruction(&Instruction::End); f.instruction(&Instruction::End);
f
}
pub(super) fn emit_map_has(rt: &RuntimeFuncIndices) -> Function {
let mut f = Function::new(vec![
(1, ValType::I32), (1, ValType::I32), ]);
f.instruction(&Instruction::LocalGet(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::I32Eqz);
f.instruction(&Instruction::BrIf(1));
f.instruction(&Instruction::LocalGet(2));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::Call(rt.obj_field));
f.instruction(&Instruction::I32WrapI64); f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::Call(rt.obj_field));
f.instruction(&Instruction::I32WrapI64); f.instruction(&Instruction::LocalGet(1));
f.instruction(&Instruction::Call(rt.str_eq));
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(2));
f.instruction(&Instruction::I32Const(1));
f.instruction(&Instruction::Call(rt.obj_field_i32));
f.instruction(&Instruction::LocalSet(2));
f.instruction(&Instruction::Br(0));
f.instruction(&Instruction::End);
f.instruction(&Instruction::End);
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::End);
f
}
pub(super) fn emit_map_keys(rt: &RuntimeFuncIndices) -> Function {
let mut f = Function::new(vec![
(1, ValType::I32), (1, ValType::I32), (1, ValType::I64), ]);
f.instruction(&Instruction::LocalGet(0));
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(1));
f.instruction(&Instruction::I32Eqz);
f.instruction(&Instruction::BrIf(1));
f.instruction(&Instruction::LocalGet(1));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::Call(rt.obj_field)); f.instruction(&Instruction::I32WrapI64);
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::Call(rt.obj_field)); f.instruction(&Instruction::LocalSet(3));
f.instruction(&Instruction::LocalGet(3));
f.instruction(&Instruction::LocalGet(2));
f.instruction(&Instruction::I32Const(1));
f.instruction(&Instruction::Call(rt.list_cons));
f.instruction(&Instruction::LocalSet(2));
f.instruction(&Instruction::LocalGet(1));
f.instruction(&Instruction::I32Const(1));
f.instruction(&Instruction::Call(rt.obj_field_i32));
f.instruction(&Instruction::LocalSet(1));
f.instruction(&Instruction::Br(0));
f.instruction(&Instruction::End);
f.instruction(&Instruction::End);
f.instruction(&Instruction::LocalGet(2));
f.instruction(&Instruction::Call(rt.list_reverse));
f.instruction(&Instruction::End);
f
}
pub(super) fn emit_map_entries(rt: &RuntimeFuncIndices) -> Function {
let mut f = Function::new(vec![
(1, ValType::I32), (1, ValType::I32), ]);
f.instruction(&Instruction::LocalGet(0));
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(1));
f.instruction(&Instruction::I32Eqz);
f.instruction(&Instruction::BrIf(1));
f.instruction(&Instruction::LocalGet(1));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::Call(rt.obj_field));
f.instruction(&Instruction::LocalGet(2));
f.instruction(&Instruction::I32Const(1));
f.instruction(&Instruction::Call(rt.list_cons));
f.instruction(&Instruction::LocalSet(2));
f.instruction(&Instruction::LocalGet(1));
f.instruction(&Instruction::I32Const(1));
f.instruction(&Instruction::Call(rt.obj_field_i32));
f.instruction(&Instruction::LocalSet(1));
f.instruction(&Instruction::Br(0));
f.instruction(&Instruction::End);
f.instruction(&Instruction::End);
f.instruction(&Instruction::LocalGet(2));
f.instruction(&Instruction::Call(rt.list_reverse));
f.instruction(&Instruction::End);
f
}