Update API comments, refine footprint of wasm loader (#256)

and fix issues of get native stack boundary
This commit is contained in:
wenyongh 2020-05-15 17:44:36 +08:00 committed by GitHub
parent 1362b6d81f
commit a0bb761beb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 269 additions and 264 deletions

View File

@ -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,

View File

@ -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)

View File

@ -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);

View File

@ -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;
}