mirror of
https://github.com/bytecodealliance/wasm-micro-runtime.git
synced 2025-05-09 13:16:26 +00:00
Update API comments, refine footprint of wasm loader (#256)
and fix issues of get native stack boundary
This commit is contained in:
parent
1362b6d81f
commit
a0bb761beb
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user