diff options
Diffstat (limited to 'fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/iwasm/fast-jit/fe/jit_emit_table.c')
-rw-r--r-- | fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/iwasm/fast-jit/fe/jit_emit_table.c | 318 |
1 files changed, 318 insertions, 0 deletions
diff --git a/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/iwasm/fast-jit/fe/jit_emit_table.c b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/iwasm/fast-jit/fe/jit_emit_table.c new file mode 100644 index 000000000..9fb61931f --- /dev/null +++ b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/iwasm/fast-jit/fe/jit_emit_table.c @@ -0,0 +1,318 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + */ + +#include "jit_emit_table.h" +#include "jit_emit_exception.h" +#include "jit_emit_function.h" +#include "../../interpreter/wasm_runtime.h" +#include "../jit_frontend.h" + +#if WASM_ENABLE_REF_TYPES != 0 +bool +jit_compile_op_elem_drop(JitCompContext *cc, uint32 tbl_seg_idx) +{ + JitReg module, tbl_segs; + + module = get_module_reg(cc->jit_frame); + + tbl_segs = jit_cc_new_reg_ptr(cc); + GEN_INSN(LDPTR, tbl_segs, module, + NEW_CONST(I32, offsetof(WASMModule, table_segments))); + + GEN_INSN(STI32, NEW_CONST(I32, true), tbl_segs, + NEW_CONST(I32, tbl_seg_idx * sizeof(WASMTableSeg) + + offsetof(WASMTableSeg, is_dropped))); + return true; +} + +bool +jit_compile_op_table_get(JitCompContext *cc, uint32 tbl_idx) +{ + JitReg elem_idx, tbl_sz, tbl_elems, elem_idx_long, offset, res; + + POP_I32(elem_idx); + + /* if (elem_idx >= tbl_sz) goto exception; */ + tbl_sz = get_table_cur_size_reg(cc->jit_frame, tbl_idx); + GEN_INSN(CMP, cc->cmp_reg, elem_idx, tbl_sz); + if (!jit_emit_exception(cc, EXCE_OUT_OF_BOUNDS_TABLE_ACCESS, JIT_OP_BGEU, + cc->cmp_reg, NULL)) + goto fail; + + elem_idx_long = jit_cc_new_reg_I64(cc); + GEN_INSN(I32TOI64, elem_idx_long, elem_idx); + + offset = jit_cc_new_reg_I64(cc); + GEN_INSN(MUL, offset, elem_idx_long, NEW_CONST(I64, sizeof(uint32))); + + res = jit_cc_new_reg_I32(cc); + tbl_elems = get_table_elems_reg(cc->jit_frame, tbl_idx); + GEN_INSN(LDI32, res, tbl_elems, offset); + PUSH_I32(res); + + return true; +fail: + return false; +} + +bool +jit_compile_op_table_set(JitCompContext *cc, uint32 tbl_idx) +{ + JitReg elem_idx, elem_val, tbl_sz, tbl_elems, elem_idx_long, offset; + + POP_I32(elem_val); + POP_I32(elem_idx); + + /* if (elem_idx >= tbl_sz) goto exception; */ + tbl_sz = get_table_cur_size_reg(cc->jit_frame, tbl_idx); + GEN_INSN(CMP, cc->cmp_reg, elem_idx, tbl_sz); + if (!jit_emit_exception(cc, EXCE_OUT_OF_BOUNDS_TABLE_ACCESS, JIT_OP_BGEU, + cc->cmp_reg, NULL)) + goto fail; + + elem_idx_long = jit_cc_new_reg_I64(cc); + GEN_INSN(I32TOI64, elem_idx_long, elem_idx); + + offset = jit_cc_new_reg_I64(cc); + GEN_INSN(MUL, offset, elem_idx_long, NEW_CONST(I64, sizeof(uint32))); + + tbl_elems = get_table_elems_reg(cc->jit_frame, tbl_idx); + GEN_INSN(STI32, elem_val, tbl_elems, offset); + + return true; +fail: + return false; +} + +static int +wasm_init_table(WASMModuleInstance *inst, uint32 tbl_idx, uint32 elem_idx, + uint32 dst, uint32 len, uint32 src) +{ + WASMTableInstance *tbl; + uint32 tbl_sz; + WASMTableSeg *elem; + uint32 elem_len; + + tbl = inst->tables[tbl_idx]; + tbl_sz = tbl->cur_size; + if (dst > tbl_sz || tbl_sz - dst < len) + goto out_of_bounds; + + elem = inst->module->table_segments + elem_idx; + elem_len = elem->function_count; + if (src > elem_len || elem_len - src < len) + goto out_of_bounds; + + bh_memcpy_s((uint8 *)tbl + offsetof(WASMTableInstance, elems) + + dst * sizeof(uint32), + (uint32)((tbl_sz - dst) * sizeof(uint32)), + elem->func_indexes + src, (uint32)(len * sizeof(uint32))); + + return 0; +out_of_bounds: + wasm_set_exception(inst, "out of bounds table access"); + return -1; +} + +bool +jit_compile_op_table_init(JitCompContext *cc, uint32 tbl_idx, + uint32 tbl_seg_idx) +{ + JitReg len, src, dst, res; + JitReg args[6] = { 0 }; + + POP_I32(len); + POP_I32(src); + POP_I32(dst); + + res = jit_cc_new_reg_I32(cc); + args[0] = get_module_inst_reg(cc->jit_frame); + args[1] = NEW_CONST(I32, tbl_idx); + args[2] = NEW_CONST(I32, tbl_seg_idx); + args[3] = dst; + args[4] = len; + args[5] = src; + + if (!jit_emit_callnative(cc, wasm_init_table, res, args, + sizeof(args) / sizeof(args[0]))) + goto fail; + + GEN_INSN(CMP, cc->cmp_reg, res, NEW_CONST(I32, 0)); + if (!jit_emit_exception(cc, EXCE_ALREADY_THROWN, JIT_OP_BLTS, cc->cmp_reg, + NULL)) + goto fail; + + return true; +fail: + return false; +} + +static int +wasm_copy_table(WASMModuleInstance *inst, uint32 src_tbl_idx, + uint32 dst_tbl_idx, uint32 dst_offset, uint32 len, + uint32 src_offset) +{ + WASMTableInstance *src_tbl, *dst_tbl; + uint32 src_tbl_sz, dst_tbl_sz; + + src_tbl = inst->tables[src_tbl_idx]; + src_tbl_sz = src_tbl->cur_size; + if (src_offset > src_tbl_sz || src_tbl_sz - src_offset < len) + goto out_of_bounds; + + dst_tbl = inst->tables[dst_tbl_idx]; + dst_tbl_sz = dst_tbl->cur_size; + if (dst_offset > dst_tbl_sz || dst_tbl_sz - dst_offset < len) + goto out_of_bounds; + + bh_memmove_s((uint8 *)dst_tbl + offsetof(WASMTableInstance, elems) + + dst_offset * sizeof(uint32), + (uint32)((dst_tbl_sz - dst_offset) * sizeof(uint32)), + (uint8 *)src_tbl + offsetof(WASMTableInstance, elems) + + src_offset * sizeof(uint32), + (uint32)(len * sizeof(uint32))); + + return 0; +out_of_bounds: + wasm_set_exception(inst, "out of bounds table access"); + return -1; +} + +bool +jit_compile_op_table_copy(JitCompContext *cc, uint32 src_tbl_idx, + uint32 dst_tbl_idx) +{ + JitReg len, src, dst, res; + JitReg args[6] = { 0 }; + + POP_I32(len); + POP_I32(src); + POP_I32(dst); + + res = jit_cc_new_reg_I32(cc); + args[0] = get_module_inst_reg(cc->jit_frame); + args[1] = NEW_CONST(I32, src_tbl_idx); + args[2] = NEW_CONST(I32, dst_tbl_idx); + args[3] = dst; + args[4] = len; + args[5] = src; + + if (!jit_emit_callnative(cc, wasm_copy_table, res, args, + sizeof(args) / sizeof(args[0]))) + goto fail; + + GEN_INSN(CMP, cc->cmp_reg, res, NEW_CONST(I32, 0)); + if (!jit_emit_exception(cc, EXCE_ALREADY_THROWN, JIT_OP_BLTS, cc->cmp_reg, + NULL)) + goto fail; + + return true; +fail: + return false; +} + +bool +jit_compile_op_table_size(JitCompContext *cc, uint32 tbl_idx) +{ + JitReg res; + + res = get_table_cur_size_reg(cc->jit_frame, tbl_idx); + PUSH_I32(res); + + return true; +fail: + return false; +} + +bool +jit_compile_op_table_grow(JitCompContext *cc, uint32 tbl_idx) +{ + JitReg tbl_sz, n, val, enlarge_ret, res; + JitReg args[4] = { 0 }; + + POP_I32(n); + POP_I32(val); + + tbl_sz = get_table_cur_size_reg(cc->jit_frame, tbl_idx); + + enlarge_ret = jit_cc_new_reg_I32(cc); + args[0] = get_module_inst_reg(cc->jit_frame); + args[1] = NEW_CONST(I32, tbl_idx); + args[2] = n; + args[3] = val; + + if (!jit_emit_callnative(cc, wasm_enlarge_table, enlarge_ret, args, + sizeof(args) / sizeof(args[0]))) + goto fail; + + /* Convert bool to uint32 */ + GEN_INSN(AND, enlarge_ret, enlarge_ret, NEW_CONST(I32, 0xFF)); + + res = jit_cc_new_reg_I32(cc); + GEN_INSN(CMP, cc->cmp_reg, enlarge_ret, NEW_CONST(I32, 1)); + GEN_INSN(SELECTEQ, res, cc->cmp_reg, tbl_sz, NEW_CONST(I32, -1)); + PUSH_I32(res); + + /* Ensure a refresh in next get memory related registers */ + clear_table_regs(cc->jit_frame); + return true; +fail: + return false; +} + +static int +wasm_fill_table(WASMModuleInstance *inst, uint32 tbl_idx, uint32 dst, + uint32 val, uint32 len) +{ + WASMTableInstance *tbl; + uint32 tbl_sz; + + tbl = inst->tables[tbl_idx]; + tbl_sz = tbl->cur_size; + + if (dst > tbl_sz || tbl_sz - dst < len) + goto out_of_bounds; + + for (; len != 0; dst++, len--) { + tbl->elems[dst] = val; + } + + return 0; +out_of_bounds: + wasm_set_exception(inst, "out of bounds table access"); + return -1; +} + +bool +jit_compile_op_table_fill(JitCompContext *cc, uint32 tbl_idx) +{ + JitReg len, val, dst, res; + JitReg args[5] = { 0 }; + + POP_I32(len); + POP_I32(val); + POP_I32(dst); + + res = jit_cc_new_reg_I32(cc); + args[0] = get_module_inst_reg(cc->jit_frame); + args[1] = NEW_CONST(I32, tbl_idx); + args[2] = dst; + args[3] = val; + args[4] = len; + + if (!jit_emit_callnative(cc, wasm_fill_table, res, args, + sizeof(args) / sizeof(args[0]))) + goto fail; + + GEN_INSN(CMP, cc->cmp_reg, res, NEW_CONST(I32, 0)); + if (!jit_emit_exception(cc, EXCE_ALREADY_THROWN, JIT_OP_BLTS, cc->cmp_reg, + NULL)) + goto fail; + + return true; +fail: + return false; +} +#endif |