mirror of
https://github.com/bytecodealliance/wasm-micro-runtime.git
synced 2024-11-26 15:32:05 +00:00
fix problem about local in fast-interp (#406)
This commit is contained in:
parent
c59bfe24fb
commit
4bfcbc2cab
|
@ -4273,24 +4273,30 @@ preserve_referenced_local(WASMLoaderContext *loader_ctx, uint8 opcode,
|
|||
uint32 local_index, uint32 local_type, bool *preserved,
|
||||
char *error_buf, uint32 error_buf_size)
|
||||
{
|
||||
uint32 i = 0;
|
||||
int16 preserved_offset = (int16)local_index;
|
||||
|
||||
*preserved = false;
|
||||
for (uint32 i = 0; i < loader_ctx->stack_cell_num; i++) {
|
||||
while (i < loader_ctx->stack_cell_num) {
|
||||
uint8 cur_type = loader_ctx->frame_ref_bottom[i];
|
||||
|
||||
/* move previous local into dynamic space before a set/tee_local opcode */
|
||||
if (loader_ctx->frame_offset_bottom[i] == (int16)local_index) {
|
||||
if (preserved_offset == (int16)local_index) {
|
||||
if (!(*preserved)) {
|
||||
*preserved = true;
|
||||
skip_label();
|
||||
preserved_offset = loader_ctx->preserved_local_offset;
|
||||
if (loader_ctx->p_code_compiled) {
|
||||
bh_assert(preserved_offset != (int16)local_index);
|
||||
}
|
||||
if (local_type == VALUE_TYPE_I32
|
||||
|| local_type == VALUE_TYPE_F32) {
|
||||
preserved_offset = loader_ctx->preserved_local_offset;
|
||||
/* Only increase preserve offset in the second traversal */
|
||||
if (loader_ctx->p_code_compiled)
|
||||
loader_ctx->preserved_local_offset++;
|
||||
emit_label(EXT_OP_COPY_STACK_TOP);
|
||||
}
|
||||
else {
|
||||
preserved_offset = loader_ctx->preserved_local_offset;
|
||||
if (loader_ctx->p_code_compiled)
|
||||
loader_ctx->preserved_local_offset += 2;
|
||||
emit_label(EXT_OP_COPY_STACK_TOP_I64);
|
||||
|
@ -4301,6 +4307,11 @@ preserve_referenced_local(WASMLoaderContext *loader_ctx, uint8 opcode,
|
|||
}
|
||||
loader_ctx->frame_offset_bottom[i] = preserved_offset;
|
||||
}
|
||||
|
||||
if (cur_type == VALUE_TYPE_I32 || cur_type == VALUE_TYPE_F32)
|
||||
i++;
|
||||
else
|
||||
i += 2;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -4311,6 +4322,38 @@ fail:
|
|||
#endif
|
||||
}
|
||||
|
||||
static bool
|
||||
preserve_local_for_block(WASMLoaderContext *loader_ctx, uint8 opcode,
|
||||
char *error_buf, uint32 error_buf_size)
|
||||
{
|
||||
uint32 i = 0;
|
||||
bool preserve_local;
|
||||
|
||||
/* preserve locals before blocks to ensure that "tee/set_local" inside
|
||||
blocks will not influence the value of these locals */
|
||||
while (i < loader_ctx->stack_cell_num) {
|
||||
int16 cur_offset = loader_ctx->frame_offset_bottom[i];
|
||||
uint8 cur_type = loader_ctx->frame_ref_bottom[i];
|
||||
|
||||
if ((cur_offset < loader_ctx->start_dynamic_offset)
|
||||
&& (cur_offset >= 0)) {
|
||||
if (!(preserve_referenced_local(loader_ctx, opcode, cur_offset,
|
||||
cur_type, &preserve_local,
|
||||
error_buf, error_buf_size)))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (cur_type == VALUE_TYPE_I32 || cur_type == VALUE_TYPE_F32) {
|
||||
i++;
|
||||
}
|
||||
else {
|
||||
i += 2;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
add_label_patch_to_list(BranchBlock *frame_csp,
|
||||
uint8 patch_type, uint8 *p_code_compiled,
|
||||
|
@ -5387,6 +5430,13 @@ fail:
|
|||
#define BLOCK_HAS_PARAM(block_type) \
|
||||
(!block_type.is_value_type && block_type.u.type->param_count > 0)
|
||||
|
||||
#define PRESERVE_LOCAL_FOR_BLOCK() do { \
|
||||
if (!(preserve_local_for_block(loader_ctx, opcode, \
|
||||
error_buf, error_buf_size))) { \
|
||||
goto fail; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
static bool
|
||||
wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func,
|
||||
BlockAddr *block_addr_cache,
|
||||
|
@ -5475,10 +5525,16 @@ re_scan:
|
|||
break;
|
||||
|
||||
case WASM_OP_IF:
|
||||
#if WASM_ENABLE_FAST_INTERP != 0
|
||||
PRESERVE_LOCAL_FOR_BLOCK();
|
||||
#endif
|
||||
POP_I32();
|
||||
goto handle_op_block_and_loop;
|
||||
case WASM_OP_BLOCK:
|
||||
case WASM_OP_LOOP:
|
||||
#if WASM_ENABLE_FAST_INTERP != 0
|
||||
PRESERVE_LOCAL_FOR_BLOCK();
|
||||
#endif
|
||||
handle_op_block_and_loop:
|
||||
{
|
||||
uint8 value_type;
|
||||
|
|
|
@ -3172,24 +3172,30 @@ preserve_referenced_local(WASMLoaderContext *loader_ctx, uint8 opcode,
|
|||
uint32 local_index, uint32 local_type, bool *preserved,
|
||||
char *error_buf, uint32 error_buf_size)
|
||||
{
|
||||
uint32 i = 0;
|
||||
int16 preserved_offset = (int16)local_index;
|
||||
|
||||
*preserved = false;
|
||||
for (uint32 i = 0; i < loader_ctx->stack_cell_num; i++) {
|
||||
while (i < loader_ctx->stack_cell_num) {
|
||||
uint8 cur_type = loader_ctx->frame_ref_bottom[i];
|
||||
|
||||
/* move previous local into dynamic space before a set/tee_local opcode */
|
||||
if (loader_ctx->frame_offset_bottom[i] == (int16)local_index) {
|
||||
if (preserved_offset == (int16)local_index) {
|
||||
if (!(*preserved)) {
|
||||
*preserved = true;
|
||||
skip_label();
|
||||
preserved_offset = loader_ctx->preserved_local_offset;
|
||||
if (loader_ctx->p_code_compiled) {
|
||||
bh_assert(preserved_offset != (int16)local_index);
|
||||
}
|
||||
if (local_type == VALUE_TYPE_I32
|
||||
|| local_type == VALUE_TYPE_F32) {
|
||||
preserved_offset = loader_ctx->preserved_local_offset;
|
||||
/* Only increase preserve offset in the second traversal */
|
||||
if (loader_ctx->p_code_compiled)
|
||||
loader_ctx->preserved_local_offset++;
|
||||
emit_label(EXT_OP_COPY_STACK_TOP);
|
||||
}
|
||||
else {
|
||||
preserved_offset = loader_ctx->preserved_local_offset;
|
||||
if (loader_ctx->p_code_compiled)
|
||||
loader_ctx->preserved_local_offset += 2;
|
||||
emit_label(EXT_OP_COPY_STACK_TOP_I64);
|
||||
|
@ -3200,6 +3206,11 @@ preserve_referenced_local(WASMLoaderContext *loader_ctx, uint8 opcode,
|
|||
}
|
||||
loader_ctx->frame_offset_bottom[i] = preserved_offset;
|
||||
}
|
||||
|
||||
if (cur_type == VALUE_TYPE_I32 || cur_type == VALUE_TYPE_F32)
|
||||
i++;
|
||||
else
|
||||
i += 2;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -3210,6 +3221,38 @@ fail:
|
|||
#endif
|
||||
}
|
||||
|
||||
static bool
|
||||
preserve_local_for_block(WASMLoaderContext *loader_ctx, uint8 opcode,
|
||||
char *error_buf, uint32 error_buf_size)
|
||||
{
|
||||
uint32 i = 0;
|
||||
bool preserve_local;
|
||||
|
||||
/* preserve locals before blocks to ensure that "tee/set_local" inside
|
||||
blocks will not influence the value of these locals */
|
||||
while (i < loader_ctx->stack_cell_num) {
|
||||
int16 cur_offset = loader_ctx->frame_offset_bottom[i];
|
||||
uint8 cur_type = loader_ctx->frame_ref_bottom[i];
|
||||
|
||||
if ((cur_offset < loader_ctx->start_dynamic_offset)
|
||||
&& (cur_offset >= 0)) {
|
||||
if (!(preserve_referenced_local(loader_ctx, opcode, cur_offset,
|
||||
cur_type, &preserve_local,
|
||||
error_buf, error_buf_size)))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (cur_type == VALUE_TYPE_I32 || cur_type == VALUE_TYPE_F32) {
|
||||
i++;
|
||||
}
|
||||
else {
|
||||
i += 2;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
add_label_patch_to_list(BranchBlock *frame_csp,
|
||||
uint8 patch_type, uint8 *p_code_compiled,
|
||||
|
@ -4218,6 +4261,13 @@ fail:
|
|||
#define BLOCK_HAS_PARAM(block_type) \
|
||||
(!block_type.is_value_type && block_type.u.type->param_count > 0)
|
||||
|
||||
#define PRESERVE_LOCAL_FOR_BLOCK() do { \
|
||||
if (!(preserve_local_for_block(loader_ctx, opcode, \
|
||||
error_buf, error_buf_size))) { \
|
||||
goto fail; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
static bool
|
||||
wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func,
|
||||
BlockAddr *block_addr_cache,
|
||||
|
@ -4306,10 +4356,16 @@ re_scan:
|
|||
break;
|
||||
|
||||
case WASM_OP_IF:
|
||||
#if WASM_ENABLE_FAST_INTERP != 0
|
||||
PRESERVE_LOCAL_FOR_BLOCK();
|
||||
#endif
|
||||
POP_I32();
|
||||
goto handle_op_block_and_loop;
|
||||
case WASM_OP_BLOCK:
|
||||
case WASM_OP_LOOP:
|
||||
#if WASM_ENABLE_FAST_INTERP != 0
|
||||
PRESERVE_LOCAL_FOR_BLOCK();
|
||||
#endif
|
||||
handle_op_block_and_loop:
|
||||
{
|
||||
uint8 value_type;
|
||||
|
|
|
@ -10,6 +10,8 @@ else()
|
|||
enable_language (ASM_MASM)
|
||||
endif()
|
||||
|
||||
set (CMAKE_CXX_STANDARD 14)
|
||||
|
||||
if (NOT DEFINED WAMR_BUILD_PLATFORM)
|
||||
set (WAMR_BUILD_PLATFORM "linux")
|
||||
endif()
|
||||
|
|
Loading…
Reference in New Issue
Block a user