mirror of
https://github.com/bytecodealliance/wasm-micro-runtime.git
synced 2025-05-08 20:56:13 +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,
|
uint32 local_index, uint32 local_type, bool *preserved,
|
||||||
char *error_buf, uint32 error_buf_size)
|
char *error_buf, uint32 error_buf_size)
|
||||||
{
|
{
|
||||||
|
uint32 i = 0;
|
||||||
int16 preserved_offset = (int16)local_index;
|
int16 preserved_offset = (int16)local_index;
|
||||||
|
|
||||||
*preserved = false;
|
*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 */
|
/* move previous local into dynamic space before a set/tee_local opcode */
|
||||||
if (loader_ctx->frame_offset_bottom[i] == (int16)local_index) {
|
if (loader_ctx->frame_offset_bottom[i] == (int16)local_index) {
|
||||||
if (preserved_offset == (int16)local_index) {
|
if (!(*preserved)) {
|
||||||
*preserved = true;
|
*preserved = true;
|
||||||
skip_label();
|
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
|
if (local_type == VALUE_TYPE_I32
|
||||||
|| local_type == VALUE_TYPE_F32) {
|
|| local_type == VALUE_TYPE_F32) {
|
||||||
preserved_offset = loader_ctx->preserved_local_offset;
|
|
||||||
/* Only increase preserve offset in the second traversal */
|
/* Only increase preserve offset in the second traversal */
|
||||||
if (loader_ctx->p_code_compiled)
|
if (loader_ctx->p_code_compiled)
|
||||||
loader_ctx->preserved_local_offset++;
|
loader_ctx->preserved_local_offset++;
|
||||||
emit_label(EXT_OP_COPY_STACK_TOP);
|
emit_label(EXT_OP_COPY_STACK_TOP);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
preserved_offset = loader_ctx->preserved_local_offset;
|
|
||||||
if (loader_ctx->p_code_compiled)
|
if (loader_ctx->p_code_compiled)
|
||||||
loader_ctx->preserved_local_offset += 2;
|
loader_ctx->preserved_local_offset += 2;
|
||||||
emit_label(EXT_OP_COPY_STACK_TOP_I64);
|
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;
|
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;
|
return true;
|
||||||
|
@ -4311,6 +4322,38 @@ fail:
|
||||||
#endif
|
#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
|
static bool
|
||||||
add_label_patch_to_list(BranchBlock *frame_csp,
|
add_label_patch_to_list(BranchBlock *frame_csp,
|
||||||
uint8 patch_type, uint8 *p_code_compiled,
|
uint8 patch_type, uint8 *p_code_compiled,
|
||||||
|
@ -5387,6 +5430,13 @@ fail:
|
||||||
#define BLOCK_HAS_PARAM(block_type) \
|
#define BLOCK_HAS_PARAM(block_type) \
|
||||||
(!block_type.is_value_type && block_type.u.type->param_count > 0)
|
(!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
|
static bool
|
||||||
wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func,
|
wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func,
|
||||||
BlockAddr *block_addr_cache,
|
BlockAddr *block_addr_cache,
|
||||||
|
@ -5475,10 +5525,16 @@ re_scan:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WASM_OP_IF:
|
case WASM_OP_IF:
|
||||||
|
#if WASM_ENABLE_FAST_INTERP != 0
|
||||||
|
PRESERVE_LOCAL_FOR_BLOCK();
|
||||||
|
#endif
|
||||||
POP_I32();
|
POP_I32();
|
||||||
goto handle_op_block_and_loop;
|
goto handle_op_block_and_loop;
|
||||||
case WASM_OP_BLOCK:
|
case WASM_OP_BLOCK:
|
||||||
case WASM_OP_LOOP:
|
case WASM_OP_LOOP:
|
||||||
|
#if WASM_ENABLE_FAST_INTERP != 0
|
||||||
|
PRESERVE_LOCAL_FOR_BLOCK();
|
||||||
|
#endif
|
||||||
handle_op_block_and_loop:
|
handle_op_block_and_loop:
|
||||||
{
|
{
|
||||||
uint8 value_type;
|
uint8 value_type;
|
||||||
|
|
|
@ -3172,24 +3172,30 @@ preserve_referenced_local(WASMLoaderContext *loader_ctx, uint8 opcode,
|
||||||
uint32 local_index, uint32 local_type, bool *preserved,
|
uint32 local_index, uint32 local_type, bool *preserved,
|
||||||
char *error_buf, uint32 error_buf_size)
|
char *error_buf, uint32 error_buf_size)
|
||||||
{
|
{
|
||||||
|
uint32 i = 0;
|
||||||
int16 preserved_offset = (int16)local_index;
|
int16 preserved_offset = (int16)local_index;
|
||||||
|
|
||||||
*preserved = false;
|
*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 */
|
/* move previous local into dynamic space before a set/tee_local opcode */
|
||||||
if (loader_ctx->frame_offset_bottom[i] == (int16)local_index) {
|
if (loader_ctx->frame_offset_bottom[i] == (int16)local_index) {
|
||||||
if (preserved_offset == (int16)local_index) {
|
if (!(*preserved)) {
|
||||||
*preserved = true;
|
*preserved = true;
|
||||||
skip_label();
|
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
|
if (local_type == VALUE_TYPE_I32
|
||||||
|| local_type == VALUE_TYPE_F32) {
|
|| local_type == VALUE_TYPE_F32) {
|
||||||
preserved_offset = loader_ctx->preserved_local_offset;
|
|
||||||
/* Only increase preserve offset in the second traversal */
|
/* Only increase preserve offset in the second traversal */
|
||||||
if (loader_ctx->p_code_compiled)
|
if (loader_ctx->p_code_compiled)
|
||||||
loader_ctx->preserved_local_offset++;
|
loader_ctx->preserved_local_offset++;
|
||||||
emit_label(EXT_OP_COPY_STACK_TOP);
|
emit_label(EXT_OP_COPY_STACK_TOP);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
preserved_offset = loader_ctx->preserved_local_offset;
|
|
||||||
if (loader_ctx->p_code_compiled)
|
if (loader_ctx->p_code_compiled)
|
||||||
loader_ctx->preserved_local_offset += 2;
|
loader_ctx->preserved_local_offset += 2;
|
||||||
emit_label(EXT_OP_COPY_STACK_TOP_I64);
|
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;
|
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;
|
return true;
|
||||||
|
@ -3210,6 +3221,38 @@ fail:
|
||||||
#endif
|
#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
|
static bool
|
||||||
add_label_patch_to_list(BranchBlock *frame_csp,
|
add_label_patch_to_list(BranchBlock *frame_csp,
|
||||||
uint8 patch_type, uint8 *p_code_compiled,
|
uint8 patch_type, uint8 *p_code_compiled,
|
||||||
|
@ -4218,6 +4261,13 @@ fail:
|
||||||
#define BLOCK_HAS_PARAM(block_type) \
|
#define BLOCK_HAS_PARAM(block_type) \
|
||||||
(!block_type.is_value_type && block_type.u.type->param_count > 0)
|
(!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
|
static bool
|
||||||
wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func,
|
wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func,
|
||||||
BlockAddr *block_addr_cache,
|
BlockAddr *block_addr_cache,
|
||||||
|
@ -4306,10 +4356,16 @@ re_scan:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WASM_OP_IF:
|
case WASM_OP_IF:
|
||||||
|
#if WASM_ENABLE_FAST_INTERP != 0
|
||||||
|
PRESERVE_LOCAL_FOR_BLOCK();
|
||||||
|
#endif
|
||||||
POP_I32();
|
POP_I32();
|
||||||
goto handle_op_block_and_loop;
|
goto handle_op_block_and_loop;
|
||||||
case WASM_OP_BLOCK:
|
case WASM_OP_BLOCK:
|
||||||
case WASM_OP_LOOP:
|
case WASM_OP_LOOP:
|
||||||
|
#if WASM_ENABLE_FAST_INTERP != 0
|
||||||
|
PRESERVE_LOCAL_FOR_BLOCK();
|
||||||
|
#endif
|
||||||
handle_op_block_and_loop:
|
handle_op_block_and_loop:
|
||||||
{
|
{
|
||||||
uint8 value_type;
|
uint8 value_type;
|
||||||
|
|
|
@ -10,6 +10,8 @@ else()
|
||||||
enable_language (ASM_MASM)
|
enable_language (ASM_MASM)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
set (CMAKE_CXX_STANDARD 14)
|
||||||
|
|
||||||
if (NOT DEFINED WAMR_BUILD_PLATFORM)
|
if (NOT DEFINED WAMR_BUILD_PLATFORM)
|
||||||
set (WAMR_BUILD_PLATFORM "linux")
|
set (WAMR_BUILD_PLATFORM "linux")
|
||||||
endif()
|
endif()
|
||||||
|
|
Loading…
Reference in New Issue
Block a user