diff --git a/core/iwasm/include/wasm_export.h b/core/iwasm/include/wasm_export.h index c2e142f6..0a915f83 100644 --- a/core/iwasm/include/wasm_export.h +++ b/core/iwasm/include/wasm_export.h @@ -179,7 +179,9 @@ package_type_t get_package_type(const uint8_t *buf, uint32_t size); /** - * Load a WASM module from a specified byte buffer. + * Load a WASM module from a specified byte buffer. The byte buffer can be + * WASM binary data when interpreter or JIT is enabled, or AOT binary data + * when AOT is enabled. If it is AOT binary data, it must be 4-byte aligned. * * @param buf the byte buffer which contains the WASM binary data * @param size the size of the buffer @@ -225,11 +227,13 @@ wasm_runtime_set_wasi_args(wasm_module_t module, * Instantiate a WASM module. * * @param module the WASM module to instantiate - * @param stack_size the default stack size of the module instance, a stack - * will be created when function wasm_runtime_call_wasm() is called - * to run WASM function and the exec_env argument passed to - * wasm_runtime_call_wasm() is NULL. That means this parameter is - * ignored if exec_env is not NULL. + * @param stack_size the default stack size of the module instance when the + * exec env's operation stack isn't created by user, e.g. API + * wasm_application_execute_main() and wasm_application_execute_func() + * create the operation stack internally with the stack size specified + * here. And API wasm_runtime_create_exec_env() creates the operation + * stack with stack size specified by its parameter, the stack size + * specified here is ignored. * @param heap_size the default heap size of the module instance, a heap will * be created besides the app memory space. Both wasm app and native * function can allocate memory from the heap. If heap_size is 0, the @@ -286,7 +290,7 @@ wasm_runtime_create_exec_env(wasm_module_inst_t module_inst, /** * Destroy the execution environment. * - * @param env the execution environment to destroy + * @param exec_env the execution environment to destroy */ void wasm_runtime_destroy_exec_env(wasm_exec_env_t exec_env); @@ -305,17 +309,18 @@ wasm_runtime_get_module_inst(wasm_exec_env_t exec_env); * Call the given WASM function of a WASM module instance with * arguments (bytecode and AoT). * - * @param exec_env the execution environment to call the function + * @param exec_env the execution environment to call the function, * which must be created from wasm_create_exec_env() - * @param function the function to be called + * @param function the function to call * @param argc the number of arguments - * @param argv the arguments. If the function method has return value, + * @param argv the arguments. If the function has return value, * the first (or first two in case 64-bit return value) element of * argv stores the return value of the called WASM function after this * function returns. * * @return true if success, false otherwise and exception will be thrown, - * the caller can call wasm_runtime_get_exception to get exception info. + * the caller can call wasm_runtime_get_exception to get the exception + * info. */ bool wasm_runtime_call_wasm(wasm_exec_env_t exec_env, @@ -330,8 +335,9 @@ wasm_runtime_call_wasm(wasm_exec_env_t exec_env, * @param argc the number of arguments * @param argv the arguments array * - * @return true if the main function is called, false otherwise and exception will be thrown, - * the caller can call wasm_runtime_get_exception to get exception info. + * @return true if the main function is called, false otherwise and exception + * will be thrown, the caller can call wasm_runtime_get_exception to get + * the exception info. */ bool wasm_application_execute_main(wasm_module_inst_t module_inst, @@ -346,8 +352,9 @@ wasm_application_execute_main(wasm_module_inst_t module_inst, * @param argc the number of arguments * @param argv the arguments array * - * @return true if the specified function is called, false otherwise and exception will be thrown, - * the caller can call wasm_runtime_get_exception to get exception info. + * @return true if the specified function is called, false otherwise and + * exception will be thrown, the caller can call wasm_runtime_get_exception + * to get the exception info. */ bool wasm_application_execute_func(wasm_module_inst_t module_inst, diff --git a/core/iwasm/interpreter/wasm_loader.c b/core/iwasm/interpreter/wasm_loader.c index 5c882e9d..16a5c767 100644 --- a/core/iwasm/interpreter/wasm_loader.c +++ b/core/iwasm/interpreter/wasm_loader.c @@ -42,11 +42,11 @@ set_error_buf(char *error_buf, uint32 error_buf_size, const char *string) } while (0) static bool -skip_leb(const uint8 *buf, const uint8 *buf_end, - uint32 *p_offset, uint32 maxbits, +skip_leb(const uint8 **p_buf, const uint8 *buf_end, uint32 maxbits, char* error_buf, uint32 error_buf_size) { - uint32 bcnt = 0; + const uint8 *buf = *p_buf; + uint32 offset = 0, bcnt = 0; uint64 byte; while (true) { @@ -57,51 +57,46 @@ skip_leb(const uint8 *buf, const uint8 *buf_end, return false; } - CHECK_BUF(buf, buf_end, *p_offset + 1); - byte = buf[*p_offset]; - *p_offset += 1; + CHECK_BUF(buf, buf_end, offset + 1); + byte = buf[offset]; + offset += 1; bcnt += 1; if ((byte & 0x80) == 0) { break; } } + *p_buf += offset; return true; } #define skip_leb_int64(p, p_end) do { \ - uint32 off = 0; \ - if (!skip_leb(p, p_end, &off, 64, \ + if (!skip_leb(&p, p_end, 64, \ error_buf, error_buf_size)) \ return false; \ - p += off; \ } while (0) #define skip_leb_uint32(p, p_end) do { \ - uint32 off = 0; \ - if (!skip_leb(p, p_end, &off, 32, \ + if (!skip_leb(&p, p_end, 32, \ error_buf, error_buf_size)) \ return false; \ - p += off; \ } while (0) #define skip_leb_int32(p, p_end) do { \ - uint32 off = 0; \ - if (!skip_leb(p, p_end, &off, 32, \ + if (!skip_leb(&p, p_end, 32, \ error_buf, error_buf_size)) \ return false; \ - p += off; \ } while (0) static bool -read_leb(const uint8 *buf, const uint8 *buf_end, - uint32 *p_offset, uint32 maxbits, - bool sign, uint64 *p_result, +read_leb(uint8 **p_buf, const uint8 *buf_end, + uint32 maxbits, bool sign, uint64 *p_result, char* error_buf, uint32 error_buf_size) { + const uint8 *buf = *p_buf; uint64 result = 0; uint32 shift = 0; - uint32 bcnt = 0; + uint32 offset = 0, bcnt = 0; uint64 byte; while (true) { @@ -112,9 +107,9 @@ read_leb(const uint8 *buf, const uint8 *buf_end, return false; } - CHECK_BUF(buf, buf_end, *p_offset + 1); - byte = buf[*p_offset]; - *p_offset += 1; + CHECK_BUF(buf, buf_end, offset + 1); + byte = buf[offset]; + offset += 1; result |= ((byte & 0x7f) << shift); shift += 7; bcnt += 1; @@ -160,6 +155,7 @@ read_leb(const uint8 *buf, const uint8 *buf_end, } } + *p_buf += offset; *p_result = result; return true; @@ -174,62 +170,26 @@ fail_integer_too_large: #define read_bool(p) TEMPLATE_READ_VALUE(bool, p) #define read_leb_int64(p, p_end, res) do { \ - if (p < p_end) { \ - uint8 _val = *p; \ - if (!(_val & 0x80)) { \ - res = (int64)_val; \ - if (_val & 0x40) \ - /* sign extend */ \ - res |= 0xFFFFFFFFFFFFFF80LL; \ - p++; \ - break; \ - } \ - } \ - uint32 off = 0; \ uint64 res64; \ - if (!read_leb(p, p_end, &off, 64, true, &res64, \ + if (!read_leb((uint8**)&p, p_end, 64, true, &res64,\ error_buf, error_buf_size)) \ return false; \ - p += off; \ res = (int64)res64; \ } while (0) #define read_leb_uint32(p, p_end, res) do { \ - if (p < p_end) { \ - uint8 _val = *p; \ - if (!(_val & 0x80)) { \ - res = _val; \ - p++; \ - break; \ - } \ - } \ - uint32 off = 0; \ uint64 res64; \ - if (!read_leb(p, p_end, &off, 32, false, &res64, \ + if (!read_leb((uint8**)&p, p_end, 32, false, &res64,\ error_buf, error_buf_size)) \ return false; \ - p += off; \ res = (uint32)res64; \ } while (0) #define read_leb_int32(p, p_end, res) do { \ - if (p < p_end) { \ - uint8 _val = *p; \ - if (!(_val & 0x80)) { \ - res = (int32)_val; \ - if (_val & 0x40) \ - /* sign extend */ \ - res |= 0xFFFFFF80; \ - p++; \ - break; \ - } \ - } \ - uint32 off = 0; \ uint64 res64; \ - if (!read_leb(p, p_end, &off, 32, true, &res64, \ + if (!read_leb((uint8**)&p, p_end, 32, true, &res64,\ error_buf, error_buf_size)) \ return false; \ - p += off; \ res = (int32)res64; \ } while (0) @@ -2094,15 +2054,22 @@ wasm_loader_find_block_addr(BlockAddr *block_addr_cache, { const uint8 *p = start_addr, *p_end = code_end_addr; uint8 *else_addr = NULL; - uint32 block_nested_depth = 1, count, i; + uint32 block_nested_depth = 1, count, i, j, t; uint8 opcode, u8; - BlockAddr block_stack[16] = { 0 }, *block; - uint32 j, t; i = ((uintptr_t)start_addr) % BLOCK_ADDR_CACHE_SIZE; block = block_addr_cache + BLOCK_ADDR_CONFLICT_SIZE * i; + for (j = 0; j < BLOCK_ADDR_CONFLICT_SIZE; j++) { + if (block[j].start_addr == start_addr) { + /* Cache hit */ + *p_else_addr = block[j].else_addr; + *p_end_addr = block[j].end_addr; + return true; + } + } + /* Cache unhit */ block_stack[0].start_addr = start_addr; @@ -2761,6 +2728,20 @@ wasm_loader_pop_frame_ref(WASMLoaderContext *ctx, uint8 type, return true; } +static bool +wasm_loader_push_pop_frame_ref(WASMLoaderContext *ctx, uint8 pop_cnt, + uint8 type_push, uint8 type_pop, + char *error_buf, uint32 error_buf_size) +{ + for (int i = 0; i < pop_cnt; i++) { + if (!wasm_loader_pop_frame_ref(ctx, type_pop, error_buf, error_buf_size)) + return false; + } + if (!wasm_loader_push_frame_ref(ctx, type_push, error_buf, error_buf_size)) + return false; + return true; +} + static bool wasm_loader_push_frame_csp(WASMLoaderContext *ctx, uint8 type, uint8 ret_type, uint8* start_addr, @@ -3253,6 +3234,24 @@ wasm_loader_pop_frame_offset(WASMLoaderContext *ctx, uint8 type, return true; } +static bool +wasm_loader_push_pop_frame_offset(WASMLoaderContext *ctx, uint8 pop_cnt, + uint8 type_push, uint8 type_pop, + bool disable_emit, int16 operand_offset, + char *error_buf, uint32 error_buf_size) +{ + for (int i = 0; i < pop_cnt; i++) { + if (!wasm_loader_pop_frame_offset(ctx, type_pop, error_buf, error_buf_size)) + return false; + } + if (!wasm_loader_push_frame_offset(ctx, type_push, + disable_emit, operand_offset, + error_buf, error_buf_size)) + return false; + + return true; +} + static bool wasm_loader_push_frame_ref_offset(WASMLoaderContext *ctx, uint8 type, bool disable_emit, int16 operand_offset, @@ -3279,6 +3278,22 @@ wasm_loader_pop_frame_ref_offset(WASMLoaderContext *ctx, uint8 type, return true; } +static bool +wasm_loader_push_pop_frame_ref_offset(WASMLoaderContext *ctx, uint8 pop_cnt, + uint8 type_push, uint8 type_pop, + bool disable_emit, int16 operand_offset, + char *error_buf, uint32 error_buf_size) +{ + if (!wasm_loader_push_pop_frame_ref(ctx, pop_cnt, type_push, type_pop, + error_buf, error_buf_size)) + return false; + if (!wasm_loader_push_pop_frame_offset(ctx, pop_cnt, type_push, type_pop, + disable_emit, operand_offset, + error_buf, error_buf_size)) + return false; + + return true; +} static bool wasm_loader_get_const_offset(WASMLoaderContext *ctx, uint8 type, @@ -3432,6 +3447,23 @@ fail: goto fail; \ } while (0) +#define POP_AND_PUSH(type_pop, type_push) do { \ + if (!(wasm_loader_push_pop_frame_ref_offset(loader_ctx, 1, \ + type_push, type_pop, \ + disable_emit, operand_offset, \ + error_buf, error_buf_size))) \ + goto fail; \ + } while (0) + +/* type of POPs should be the same */ +#define POP2_AND_PUSH(type_pop, type_push) do { \ + if (!(wasm_loader_push_pop_frame_ref_offset(loader_ctx, 2, \ + type_push, type_pop, \ + disable_emit, operand_offset, \ + error_buf, error_buf_size))) \ + goto fail; \ + } while (0) + #else /* WASM_ENABLE_FAST_INTERP */ #define PUSH_I32() do { \ @@ -3482,8 +3514,85 @@ fail: goto fail; \ } while (0) +#define POP_AND_PUSH(type_pop, type_push) do { \ + if (!(wasm_loader_push_pop_frame_ref(loader_ctx, 1, \ + type_push, type_pop, \ + error_buf, error_buf_size))) \ + goto fail; \ + } while (0) + +/* type of POPs should be the same */ +#define POP2_AND_PUSH(type_pop, type_push) do { \ + if (!(wasm_loader_push_pop_frame_ref(loader_ctx, 2, \ + type_push, type_pop, \ + error_buf, error_buf_size))) \ + goto fail; \ + } while (0) #endif /* WASM_ENABLE_FAST_INTERP */ +#if WASM_ENABLE_FAST_INTERP != 0 + +static bool +reserve_block_ret(WASMLoaderContext *loader_ctx, uint8 opcode, bool disable_emit, + char *error_buf, uint32 error_buf_size) +{ + int16 operand_offset = 0; + uint8 block_depth = 0; + if (opcode == WASM_OP_ELSE) + block_depth = 1; + else + block_depth = 0; + + if ((loader_ctx->frame_csp - block_depth)->return_type != VALUE_TYPE_VOID) { + uint8 return_cells; + if ((loader_ctx->frame_csp - block_depth)->return_type == VALUE_TYPE_I32 + || (loader_ctx->frame_csp - block_depth)->return_type == VALUE_TYPE_F32) + return_cells = 1; + else + return_cells = 2; + if ((loader_ctx->frame_csp - block_depth)->dynamic_offset != + *(loader_ctx->frame_offset - return_cells)) { + + /* insert op_copy before else opcode */ + if (opcode == WASM_OP_ELSE) + skip_label(); + + if (return_cells == 1) + emit_label(EXT_OP_COPY_STACK_TOP); + else + emit_label(EXT_OP_COPY_STACK_TOP_I64); + emit_operand(loader_ctx, *(loader_ctx->frame_offset - return_cells)); + emit_operand(loader_ctx, (loader_ctx->frame_csp - block_depth)->dynamic_offset); + + if (opcode == WASM_OP_ELSE) { + *(loader_ctx->frame_offset - return_cells) = + (loader_ctx->frame_csp - block_depth)->dynamic_offset; + } + else { + loader_ctx->frame_offset -= return_cells; + loader_ctx->dynamic_offset = loader_ctx->frame_csp->dynamic_offset; + PUSH_OFFSET_TYPE((loader_ctx->frame_csp - block_depth)->return_type); + wasm_loader_emit_backspace(loader_ctx, sizeof(int16)); + } + if (opcode == WASM_OP_ELSE) + emit_label(opcode); + } + } + + return true; + +fail: + return false; +} + +#endif /* WASM_ENABLE_FAST_INTERP */ + +#define RESERVE_BLOCK_RET() do { \ + if (!reserve_block_ret(loader_ctx, opcode, disable_emit, \ + error_buf, error_buf_size)) \ + goto fail; \ + } while (0) + #define PUSH_TYPE(type) do { \ if (!(wasm_loader_push_frame_ref(loader_ctx, type, \ error_buf, error_buf_size))) \ @@ -3613,12 +3722,10 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, uint8 *param_types, ret_type, *local_types, local_type, global_type; uint16 *local_offsets, local_offset; uint32 count, i, local_idx, global_idx, u32, align, mem_offset; - uint32 cache_index, item_index; int32 i32, i32_const = 0; int64 i64; uint8 opcode, u8, block_return_type; bool return_value = false, is_i32_const = false; - BlockAddr *cache_items; WASMLoaderContext *loader_ctx; BranchBlock *frame_csp_tmp; #if WASM_ENABLE_FAST_INTERP != 0 @@ -3723,23 +3830,7 @@ re_scan: if (!is_i32_const) (loader_ctx->frame_csp - 1)->is_block_reachable = true; else { - cache_index = ((uintptr_t)(loader_ctx->frame_csp - 1)->start_addr) - & (uintptr_t)(BLOCK_ADDR_CACHE_SIZE - 1); - cache_items = block_addr_cache - + BLOCK_ADDR_CONFLICT_SIZE * cache_index; - for (item_index = 0; item_index < BLOCK_ADDR_CONFLICT_SIZE; - item_index++) { - if (cache_items[item_index].start_addr == - (loader_ctx->frame_csp - 1)->start_addr) { - (loader_ctx->frame_csp - 1)->else_addr = - cache_items[item_index].else_addr; - (loader_ctx->frame_csp - 1)->end_addr = - cache_items[item_index].end_addr; - break; - } - } - if (item_index == BLOCK_ADDR_CONFLICT_SIZE - && !wasm_loader_find_block_addr(block_addr_cache, + if (!wasm_loader_find_block_addr(block_addr_cache, (loader_ctx->frame_csp - 1)->start_addr, p_end, (loader_ctx->frame_csp - 1)->block_type, @@ -3796,27 +3887,7 @@ re_scan: loader_ctx->stack_cell_num; #if WASM_ENABLE_FAST_INTERP != 0 /* if the result of if branch is in local or const area, add a copy op */ - if ((loader_ctx->frame_csp - 1)->return_type != VALUE_TYPE_VOID) { - uint8 return_cells; - if ((loader_ctx->frame_csp - 1)->return_type == VALUE_TYPE_I32 - || (loader_ctx->frame_csp - 1)->return_type == VALUE_TYPE_F32) - return_cells = 1; - else - return_cells = 2; - if ((loader_ctx->frame_csp - 1)->dynamic_offset != - *(loader_ctx->frame_offset - return_cells)) { - skip_label(); - if (return_cells == 1) - emit_label(EXT_OP_COPY_STACK_TOP); - else - emit_label(EXT_OP_COPY_STACK_TOP_I64); - emit_operand(loader_ctx, *(loader_ctx->frame_offset - return_cells)); - emit_operand(loader_ctx, (loader_ctx->frame_csp - 1)->dynamic_offset); - *(loader_ctx->frame_offset - return_cells) = - (loader_ctx->frame_csp - 1)->dynamic_offset; - emit_label(opcode); - } - } + RESERVE_BLOCK_RET(); loader_ctx->frame_offset = loader_ctx->frame_offset_bottom + loader_ctx->stack_cell_num; emit_empty_label_addr_and_frame_ip(PATCH_END); @@ -3830,29 +3901,8 @@ re_scan: #if WASM_ENABLE_FAST_INTERP != 0 skip_label(); - // copy the result to the block return address - if (loader_ctx->frame_csp->return_type != VALUE_TYPE_VOID) { - uint8 return_cells; - if (loader_ctx->frame_csp->return_type == VALUE_TYPE_I32 - || loader_ctx->frame_csp->return_type == VALUE_TYPE_F32) - return_cells = 1; - else - return_cells = 2; - if (loader_ctx->frame_csp->dynamic_offset != - *(loader_ctx->frame_offset - return_cells)) { - if (return_cells == 1) - emit_label(EXT_OP_COPY_STACK_TOP); - else - emit_label(EXT_OP_COPY_STACK_TOP_I64); - emit_operand(loader_ctx, *(loader_ctx->frame_offset - return_cells)); - emit_operand(loader_ctx, loader_ctx->frame_csp->dynamic_offset); - } - // the frame_offset stack top should be the return address of the block - loader_ctx->frame_offset -= return_cells; - loader_ctx->dynamic_offset = loader_ctx->frame_csp->dynamic_offset; - PUSH_OFFSET_TYPE(loader_ctx->frame_csp->return_type); - wasm_loader_emit_backspace(loader_ctx, sizeof(int16)); - } + /* copy the result to the block return address */ + RESERVE_BLOCK_RET(); apply_label_patch(loader_ctx, 0, PATCH_END); free_label_patch_list(loader_ctx->frame_csp); @@ -3892,24 +3942,13 @@ handle_next_reachable_block: block_return_type = (loader_ctx->frame_csp - i)->return_type; - cache_index = ((uintptr_t)(loader_ctx->frame_csp - i)->start_addr) - & (uintptr_t)(BLOCK_ADDR_CACHE_SIZE - 1); - cache_items = block_addr_cache + BLOCK_ADDR_CONFLICT_SIZE * cache_index; - for (item_index = 0; item_index < BLOCK_ADDR_CONFLICT_SIZE; item_index++) { - if (cache_items[item_index].start_addr == (loader_ctx->frame_csp - i)->start_addr) { - (loader_ctx->frame_csp - i)->else_addr = cache_items[item_index].else_addr; - (loader_ctx->frame_csp - i)->end_addr = cache_items[item_index].end_addr; - break; - } - } - if(item_index == BLOCK_ADDR_CONFLICT_SIZE - && !wasm_loader_find_block_addr(block_addr_cache, - (loader_ctx->frame_csp - i)->start_addr, - p_end, - (loader_ctx->frame_csp - i)->block_type, - &(loader_ctx->frame_csp - i)->else_addr, - &(loader_ctx->frame_csp - i)->end_addr, - error_buf, error_buf_size)) + if(!wasm_loader_find_block_addr(block_addr_cache, + (loader_ctx->frame_csp - i)->start_addr, + p_end, + (loader_ctx->frame_csp - i)->block_type, + &(loader_ctx->frame_csp - i)->else_addr, + &(loader_ctx->frame_csp - i)->end_addr, + error_buf, error_buf_size)) goto fail; loader_ctx->stack_cell_num = (loader_ctx->frame_csp - i)->stack_cell_num; @@ -4443,8 +4482,7 @@ handle_next_reachable_block: case WASM_OP_I32_LOAD8_U: case WASM_OP_I32_LOAD16_S: case WASM_OP_I32_LOAD16_U: - POP_I32(); - PUSH_I32(); + POP_AND_PUSH(VALUE_TYPE_I32, VALUE_TYPE_I32); break; case WASM_OP_I64_LOAD: case WASM_OP_I64_LOAD8_S: @@ -4453,16 +4491,13 @@ handle_next_reachable_block: case WASM_OP_I64_LOAD16_U: case WASM_OP_I64_LOAD32_S: case WASM_OP_I64_LOAD32_U: - POP_I32(); - PUSH_I64(); + POP_AND_PUSH(VALUE_TYPE_I32, VALUE_TYPE_I64); break; case WASM_OP_F32_LOAD: - POP_I32(); - PUSH_F32(); + POP_AND_PUSH(VALUE_TYPE_I32, VALUE_TYPE_F32); break; case WASM_OP_F64_LOAD: - POP_I32(); - PUSH_F64(); + POP_AND_PUSH(VALUE_TYPE_I32, VALUE_TYPE_F64); break; /* store */ case WASM_OP_I32_STORE: @@ -4513,8 +4548,7 @@ handle_next_reachable_block: "zero flag expected"); goto fail; } - POP_I32(); - PUSH_I32(); + POP_AND_PUSH(VALUE_TYPE_I32, VALUE_TYPE_I32); func->has_op_memory_grow = true; module->possible_memory_grow = true; @@ -4566,8 +4600,7 @@ handle_next_reachable_block: break; case WASM_OP_I32_EQZ: - POP_I32(); - PUSH_I32(); + POP_AND_PUSH(VALUE_TYPE_I32, VALUE_TYPE_I32); break; case WASM_OP_I32_EQ: @@ -4580,14 +4613,11 @@ handle_next_reachable_block: case WASM_OP_I32_LE_U: case WASM_OP_I32_GE_S: case WASM_OP_I32_GE_U: - POP_I32(); - POP_I32(); - PUSH_I32(); + POP2_AND_PUSH(VALUE_TYPE_I32, VALUE_TYPE_I32); break; case WASM_OP_I64_EQZ: - POP_I64(); - PUSH_I32(); + POP_AND_PUSH(VALUE_TYPE_I64, VALUE_TYPE_I32); break; case WASM_OP_I64_EQ: @@ -4600,9 +4630,7 @@ handle_next_reachable_block: case WASM_OP_I64_LE_U: case WASM_OP_I64_GE_S: case WASM_OP_I64_GE_U: - POP_I64(); - POP_I64(); - PUSH_I32(); + POP2_AND_PUSH(VALUE_TYPE_I64, VALUE_TYPE_I32); break; case WASM_OP_F32_EQ: @@ -4611,9 +4639,7 @@ handle_next_reachable_block: case WASM_OP_F32_GT: case WASM_OP_F32_LE: case WASM_OP_F32_GE: - POP_F32(); - POP_F32(); - PUSH_I32(); + POP2_AND_PUSH(VALUE_TYPE_F32, VALUE_TYPE_I32); break; case WASM_OP_F64_EQ: @@ -4622,9 +4648,7 @@ handle_next_reachable_block: case WASM_OP_F64_GT: case WASM_OP_F64_LE: case WASM_OP_F64_GE: - POP_F64(); - POP_F64(); - PUSH_I32(); + POP2_AND_PUSH(VALUE_TYPE_F64, VALUE_TYPE_I32); break; break; @@ -4632,8 +4656,7 @@ handle_next_reachable_block: case WASM_OP_I32_CLZ: case WASM_OP_I32_CTZ: case WASM_OP_I32_POPCNT: - POP_I32(); - PUSH_I32(); + POP_AND_PUSH(VALUE_TYPE_I32, VALUE_TYPE_I32); break; case WASM_OP_I32_ADD: @@ -4651,16 +4674,13 @@ handle_next_reachable_block: case WASM_OP_I32_SHR_U: case WASM_OP_I32_ROTL: case WASM_OP_I32_ROTR: - POP_I32(); - POP_I32(); - PUSH_I32(); + POP2_AND_PUSH(VALUE_TYPE_I32, VALUE_TYPE_I32); break; case WASM_OP_I64_CLZ: case WASM_OP_I64_CTZ: case WASM_OP_I64_POPCNT: - POP_I64(); - PUSH_I64(); + POP_AND_PUSH(VALUE_TYPE_I64, VALUE_TYPE_I64); break; case WASM_OP_I64_ADD: @@ -4678,9 +4698,7 @@ handle_next_reachable_block: case WASM_OP_I64_SHR_U: case WASM_OP_I64_ROTL: case WASM_OP_I64_ROTR: - POP_I64(); - POP_I64(); - PUSH_I64(); + POP2_AND_PUSH(VALUE_TYPE_I64, VALUE_TYPE_I64); break; case WASM_OP_F32_ABS: @@ -4690,8 +4708,7 @@ handle_next_reachable_block: case WASM_OP_F32_TRUNC: case WASM_OP_F32_NEAREST: case WASM_OP_F32_SQRT: - POP_F32(); - PUSH_F32(); + POP_AND_PUSH(VALUE_TYPE_F32, VALUE_TYPE_F32); break; case WASM_OP_F32_ADD: @@ -4701,9 +4718,7 @@ handle_next_reachable_block: case WASM_OP_F32_MIN: case WASM_OP_F32_MAX: case WASM_OP_F32_COPYSIGN: - POP_F32(); - POP_F32(); - PUSH_F32(); + POP2_AND_PUSH(VALUE_TYPE_F32, VALUE_TYPE_F32); break; case WASM_OP_F64_ABS: @@ -4713,8 +4728,7 @@ handle_next_reachable_block: case WASM_OP_F64_TRUNC: case WASM_OP_F64_NEAREST: case WASM_OP_F64_SQRT: - POP_F64(); - PUSH_F64(); + POP_AND_PUSH(VALUE_TYPE_F64, VALUE_TYPE_F64); break; case WASM_OP_F64_ADD: @@ -4724,111 +4738,91 @@ handle_next_reachable_block: case WASM_OP_F64_MIN: case WASM_OP_F64_MAX: case WASM_OP_F64_COPYSIGN: - POP_F64(); - POP_F64(); - PUSH_F64(); + POP2_AND_PUSH(VALUE_TYPE_F64, VALUE_TYPE_F64); break; case WASM_OP_I32_WRAP_I64: - POP_I64(); - PUSH_I32(); + POP_AND_PUSH(VALUE_TYPE_I64, VALUE_TYPE_I32); break; case WASM_OP_I32_TRUNC_S_F32: case WASM_OP_I32_TRUNC_U_F32: - POP_F32(); - PUSH_I32(); + POP_AND_PUSH(VALUE_TYPE_F32, VALUE_TYPE_I32); break; case WASM_OP_I32_TRUNC_S_F64: case WASM_OP_I32_TRUNC_U_F64: - POP_F64(); - PUSH_I32(); + POP_AND_PUSH(VALUE_TYPE_F64, VALUE_TYPE_I32); break; case WASM_OP_I64_EXTEND_S_I32: case WASM_OP_I64_EXTEND_U_I32: - POP_I32(); - PUSH_I64(); + POP_AND_PUSH(VALUE_TYPE_I32, VALUE_TYPE_I64); break; case WASM_OP_I64_TRUNC_S_F32: case WASM_OP_I64_TRUNC_U_F32: - POP_F32(); - PUSH_I64(); + POP_AND_PUSH(VALUE_TYPE_F32, VALUE_TYPE_I64); break; case WASM_OP_I64_TRUNC_S_F64: case WASM_OP_I64_TRUNC_U_F64: - POP_F64(); - PUSH_I64(); + POP_AND_PUSH(VALUE_TYPE_F64, VALUE_TYPE_I64); break; case WASM_OP_F32_CONVERT_S_I32: case WASM_OP_F32_CONVERT_U_I32: - POP_I32(); - PUSH_F32(); + POP_AND_PUSH(VALUE_TYPE_I32, VALUE_TYPE_F32); break; case WASM_OP_F32_CONVERT_S_I64: case WASM_OP_F32_CONVERT_U_I64: - POP_I64(); - PUSH_F32(); + POP_AND_PUSH(VALUE_TYPE_I64, VALUE_TYPE_F32); break; case WASM_OP_F32_DEMOTE_F64: - POP_F64(); - PUSH_F32(); + POP_AND_PUSH(VALUE_TYPE_F64, VALUE_TYPE_F32); break; case WASM_OP_F64_CONVERT_S_I32: case WASM_OP_F64_CONVERT_U_I32: - POP_I32(); - PUSH_F64(); + POP_AND_PUSH(VALUE_TYPE_I32, VALUE_TYPE_F64); break; case WASM_OP_F64_CONVERT_S_I64: case WASM_OP_F64_CONVERT_U_I64: - POP_I64(); - PUSH_F64(); + POP_AND_PUSH(VALUE_TYPE_I64, VALUE_TYPE_F64); break; case WASM_OP_F64_PROMOTE_F32: - POP_F32(); - PUSH_F64(); + POP_AND_PUSH(VALUE_TYPE_F32, VALUE_TYPE_F64); break; case WASM_OP_I32_REINTERPRET_F32: - POP_F32(); - PUSH_I32(); + POP_AND_PUSH(VALUE_TYPE_F32, VALUE_TYPE_I32); break; case WASM_OP_I64_REINTERPRET_F64: - POP_F64(); - PUSH_I64(); + POP_AND_PUSH(VALUE_TYPE_F64, VALUE_TYPE_I64); break; case WASM_OP_F32_REINTERPRET_I32: - POP_I32(); - PUSH_F32(); + POP_AND_PUSH(VALUE_TYPE_I32, VALUE_TYPE_F32); break; case WASM_OP_F64_REINTERPRET_I64: - POP_I64(); - PUSH_F64(); + POP_AND_PUSH(VALUE_TYPE_I64, VALUE_TYPE_F64); break; case WASM_OP_I32_EXTEND8_S: case WASM_OP_I32_EXTEND16_S: - POP_I32(); - PUSH_I32(); + POP_AND_PUSH(VALUE_TYPE_I32, VALUE_TYPE_I32); break; case WASM_OP_I64_EXTEND8_S: case WASM_OP_I64_EXTEND16_S: case WASM_OP_I64_EXTEND32_S: - POP_I64(); - PUSH_I64(); + POP_AND_PUSH(VALUE_TYPE_I64, VALUE_TYPE_I64); break; case WASM_OP_MISC_PREFIX: @@ -4841,23 +4835,19 @@ handle_next_reachable_block: { case WASM_OP_I32_TRUNC_SAT_S_F32: case WASM_OP_I32_TRUNC_SAT_U_F32: - POP_F32(); - PUSH_I32(); + POP_AND_PUSH(VALUE_TYPE_F32, VALUE_TYPE_I32); break; case WASM_OP_I32_TRUNC_SAT_S_F64: case WASM_OP_I32_TRUNC_SAT_U_F64: - POP_F64(); - PUSH_I32(); + POP_AND_PUSH(VALUE_TYPE_F64, VALUE_TYPE_I32); break; case WASM_OP_I64_TRUNC_SAT_S_F32: case WASM_OP_I64_TRUNC_SAT_U_F32: - POP_F32(); - PUSH_I64(); + POP_AND_PUSH(VALUE_TYPE_F32, VALUE_TYPE_I64); break; case WASM_OP_I64_TRUNC_SAT_S_F64: case WASM_OP_I64_TRUNC_SAT_U_F64: - POP_F64(); - PUSH_I64(); + POP_AND_PUSH(VALUE_TYPE_F64, VALUE_TYPE_I64); break; default: if (error_buf != NULL) diff --git a/core/iwasm/interpreter/wasm_runtime.c b/core/iwasm/interpreter/wasm_runtime.c index 98f1bcc8..bca20e6d 100644 --- a/core/iwasm/interpreter/wasm_runtime.c +++ b/core/iwasm/interpreter/wasm_runtime.c @@ -818,10 +818,6 @@ wasm_deinstantiate(WASMModuleInstance *module_inst) if (module_inst->memory_count > 0) memories_deinstantiate(module_inst->memories, module_inst->memory_count); - else if (module_inst->memories != NULL && module_inst->global_count > 0) - /* No imported memory and defined memory, the memory is created when - global count > 0. */ - memories_deinstantiate(module_inst->memories, 1); tables_deinstantiate(module_inst->tables, module_inst->table_count); functions_deinstantiate(module_inst->functions, module_inst->function_count); diff --git a/core/shared/platform/common/posix/posix_thread.c b/core/shared/platform/common/posix/posix_thread.c index 1a32b150..9c0cf383 100644 --- a/core/shared/platform/common/posix/posix_thread.c +++ b/core/shared/platform/common/posix/posix_thread.c @@ -223,19 +223,31 @@ int os_thread_join(korp_tid thread, void **value_ptr) uint8 *os_thread_get_stack_boundary() { + pthread_t self = pthread_self(); pthread_attr_t attr; - void *addr = NULL; - size_t size; + uint8 *addr = NULL; + size_t stack_size, guard_size; - if (pthread_getattr_np(pthread_self(), &attr) == 0) { - pthread_attr_getstack(&attr, &addr, &size); - pthread_attr_destroy (&attr); +#ifdef __linux__ + if (pthread_getattr_np(self, &attr) == 0) { + pthread_attr_getstack(&attr, (void**)&addr, &stack_size); + pthread_attr_getguardsize(&attr, &guard_size); + pthread_attr_destroy(&attr); + if (guard_size < 4 * 1024) + /* Reserved 4 KB guard size at least for safety */ + guard_size = 4 * 1024; + addr += guard_size; } + (void)stack_size; +#elif defined(__APPLE__) + if ((addr = (uint8*)pthread_get_stackaddr_np(self))) { + stack_size = pthread_get_stacksize_np(self); + addr -= stack_size; + /* Reserved 4 KB guard size at least for safety */ + addr += 4 * 1024; + } +#endif - if (addr) - /* Reserved 4 KB for safety */ - return (uint8*)addr + 4 * 1024; - else - return NULL; + return addr; }