mirror of
https://github.com/bytecodealliance/wasm-micro-runtime.git
synced 2025-02-06 15:05:19 +00:00
Fix fast-interp "pre-compiled label offset out of range" issue (#2659)
When labels-as-values is enabled in a target which doesn't support unaligned address access, 16-bit offset is used to store the relative offset between two opcode labels. But it is a little small and the loader may report "pre-compiled label offset out of range" error. Emitting 32-bit data instead to resolve the issue: emit label address in 32-bit target and emit 32-bit relative offset in 64-bit target. See also: https://github.com/bytecodealliance/wasm-micro-runtime/issues/2635
This commit is contained in:
parent
9d7931e1d2
commit
d6bba13e86
|
@ -1128,12 +1128,27 @@ wasm_interp_dump_op_count()
|
|||
goto *p_label_addr; \
|
||||
} while (0)
|
||||
#else
|
||||
#define FETCH_OPCODE_AND_DISPATCH() \
|
||||
do { \
|
||||
const void *p_label_addr = label_base + *(int16 *)frame_ip; \
|
||||
frame_ip += sizeof(int16); \
|
||||
goto *p_label_addr; \
|
||||
#if UINTPTR_MAX == UINT64_MAX
|
||||
#define FETCH_OPCODE_AND_DISPATCH() \
|
||||
do { \
|
||||
const void *p_label_addr; \
|
||||
bh_assert(((uintptr_t)frame_ip & 1) == 0); \
|
||||
/* int32 relative offset was emitted in 64-bit target */ \
|
||||
p_label_addr = label_base + (int32)LOAD_U32_WITH_2U16S(frame_ip); \
|
||||
frame_ip += sizeof(int32); \
|
||||
goto *p_label_addr; \
|
||||
} while (0)
|
||||
#else
|
||||
#define FETCH_OPCODE_AND_DISPATCH() \
|
||||
do { \
|
||||
const void *p_label_addr; \
|
||||
bh_assert(((uintptr_t)frame_ip & 1) == 0); \
|
||||
/* uint32 label address was emitted in 32-bit target */ \
|
||||
p_label_addr = (void *)(uintptr_t)LOAD_U32_WITH_2U16S(frame_ip); \
|
||||
frame_ip += sizeof(int32); \
|
||||
goto *p_label_addr; \
|
||||
} while (0)
|
||||
#endif
|
||||
#endif /* end of WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS */
|
||||
#define HANDLE_OP_END() FETCH_OPCODE_AND_DISPATCH()
|
||||
|
||||
|
@ -1183,7 +1198,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
|||
register uint8 *frame_ip = &opcode_IMPDEP; /* cache of frame->ip */
|
||||
register uint32 *frame_lp = NULL; /* cache of frame->lp */
|
||||
#if WASM_ENABLE_LABELS_AS_VALUES != 0
|
||||
#if WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS == 0
|
||||
#if WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS == 0 && UINTPTR_MAX == UINT64_MAX
|
||||
/* cache of label base addr */
|
||||
register uint8 *label_base = &&HANDLE_WASM_OP_UNREACHABLE;
|
||||
#endif
|
||||
|
|
|
@ -5389,21 +5389,27 @@ fail:
|
|||
LOG_OP("\ndelete last op\n"); \
|
||||
} while (0)
|
||||
#else /* else of WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS */
|
||||
#if UINTPTR_MAX == UINT64_MAX
|
||||
#define emit_label(opcode) \
|
||||
do { \
|
||||
int32 offset = \
|
||||
(int32)((uint8 *)handle_table[opcode] - (uint8 *)handle_table[0]); \
|
||||
if (!(offset >= INT16_MIN && offset < INT16_MAX)) { \
|
||||
set_error_buf(error_buf, error_buf_size, \
|
||||
"pre-compiled label offset out of range"); \
|
||||
goto fail; \
|
||||
} \
|
||||
wasm_loader_emit_int16(loader_ctx, offset); \
|
||||
/* emit int32 relative offset in 64-bit target */ \
|
||||
wasm_loader_emit_uint32(loader_ctx, offset); \
|
||||
LOG_OP("\nemit_op [%02x]\t", opcode); \
|
||||
} while (0)
|
||||
#else
|
||||
#define emit_label(opcode) \
|
||||
do { \
|
||||
uint32 label_addr = (uint32)(uintptr_t)handle_table[opcode]; \
|
||||
/* emit uint32 label address in 32-bit target */ \
|
||||
wasm_loader_emit_uint32(loader_ctx, label_addr); \
|
||||
LOG_OP("\nemit_op [%02x]\t", opcode); \
|
||||
} while (0)
|
||||
#endif
|
||||
#define skip_label() \
|
||||
do { \
|
||||
wasm_loader_emit_backspace(loader_ctx, sizeof(int16)); \
|
||||
wasm_loader_emit_backspace(loader_ctx, sizeof(int32)); \
|
||||
LOG_OP("\ndelete last op\n"); \
|
||||
} while (0)
|
||||
#endif /* end of WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS */
|
||||
|
@ -5733,12 +5739,6 @@ preserve_referenced_local(WASMLoaderContext *loader_ctx, uint8 opcode,
|
|||
(void)error_buf;
|
||||
(void)error_buf_size;
|
||||
return true;
|
||||
#if WASM_ENABLE_LABELS_AS_VALUES != 0
|
||||
#if WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS == 0
|
||||
fail:
|
||||
return false;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
static bool
|
||||
|
@ -7793,6 +7793,9 @@ re_scan:
|
|||
uint8 ref_type;
|
||||
BranchBlock *cur_block = loader_ctx->frame_csp - 1;
|
||||
int32 available_stack_cell;
|
||||
#if WASM_ENABLE_FAST_INTERP != 0
|
||||
uint8 *p_code_compiled_tmp = loader_ctx->p_code_compiled;
|
||||
#endif
|
||||
|
||||
POP_I32();
|
||||
|
||||
|
@ -7821,26 +7824,26 @@ re_scan:
|
|||
#if WASM_ENABLE_FAST_INTERP != 0
|
||||
if (loader_ctx->p_code_compiled) {
|
||||
uint8 opcode_tmp = WASM_OP_SELECT_64;
|
||||
uint8 *p_code_compiled_tmp =
|
||||
loader_ctx->p_code_compiled - 2;
|
||||
#if WASM_ENABLE_LABELS_AS_VALUES != 0
|
||||
#if WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS != 0
|
||||
*(void **)(p_code_compiled_tmp
|
||||
- sizeof(void *)) =
|
||||
handle_table[opcode_tmp];
|
||||
#else
|
||||
#if UINTPTR_MAX == UINT64_MAX
|
||||
/* emit int32 relative offset in 64-bit target
|
||||
*/
|
||||
int32 offset =
|
||||
(int32)((uint8 *)handle_table[opcode_tmp]
|
||||
- (uint8 *)handle_table[0]);
|
||||
if (!(offset >= INT16_MIN
|
||||
&& offset < INT16_MAX)) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"pre-compiled label offset "
|
||||
"out of range");
|
||||
goto fail;
|
||||
}
|
||||
*(int16 *)(p_code_compiled_tmp
|
||||
- sizeof(int16)) = (int16)offset;
|
||||
*(int32 *)(p_code_compiled_tmp
|
||||
- sizeof(int32)) = offset;
|
||||
#else
|
||||
/* emit uint32 label address in 32-bit target */
|
||||
*(uint32 *)(p_code_compiled_tmp
|
||||
- sizeof(uint32)) =
|
||||
(uint32)(uintptr_t)handle_table[opcode_tmp];
|
||||
#endif
|
||||
#endif /* end of WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS */
|
||||
#else /* else of WASM_ENABLE_LABELS_AS_VALUES */
|
||||
#if WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS != 0
|
||||
|
@ -7934,16 +7937,17 @@ re_scan:
|
|||
*(void **)(p_code_compiled_tmp - sizeof(void *)) =
|
||||
handle_table[opcode_tmp];
|
||||
#else
|
||||
#if UINTPTR_MAX == UINT64_MAX
|
||||
/* emit int32 relative offset in 64-bit target */
|
||||
int32 offset = (int32)((uint8 *)handle_table[opcode_tmp]
|
||||
- (uint8 *)handle_table[0]);
|
||||
if (!(offset >= INT16_MIN && offset < INT16_MAX)) {
|
||||
set_error_buf(
|
||||
error_buf, error_buf_size,
|
||||
"pre-compiled label offset out of range");
|
||||
goto fail;
|
||||
}
|
||||
*(int16 *)(p_code_compiled_tmp - sizeof(int16)) =
|
||||
(int16)offset;
|
||||
*(int32 *)(p_code_compiled_tmp - sizeof(int32)) =
|
||||
offset;
|
||||
#else
|
||||
/* emit uint32 label address in 32-bit target */
|
||||
*(uint32 *)(p_code_compiled_tmp - sizeof(uint32)) =
|
||||
(uint32)(uintptr_t)handle_table[opcode_tmp];
|
||||
#endif
|
||||
#endif /* end of WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS */
|
||||
#else /* else of WASM_ENABLE_LABELS_AS_VALUES */
|
||||
#if WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS != 0
|
||||
|
|
|
@ -4009,21 +4009,27 @@ wasm_loader_pop_frame_csp(WASMLoaderContext *ctx, char *error_buf,
|
|||
LOG_OP("\ndelete last op\n"); \
|
||||
} while (0)
|
||||
#else /* else of WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS */
|
||||
#if UINTPTR_MAX == UINT64_MAX
|
||||
#define emit_label(opcode) \
|
||||
do { \
|
||||
int32 offset = \
|
||||
(int32)((uint8 *)handle_table[opcode] - (uint8 *)handle_table[0]); \
|
||||
if (!(offset >= INT16_MIN && offset < INT16_MAX)) { \
|
||||
set_error_buf(error_buf, error_buf_size, \
|
||||
"pre-compiled label offset out of range"); \
|
||||
goto fail; \
|
||||
} \
|
||||
wasm_loader_emit_int16(loader_ctx, offset); \
|
||||
/* emit int32 relative offset in 64-bit target */ \
|
||||
wasm_loader_emit_uint32(loader_ctx, offset); \
|
||||
LOG_OP("\nemit_op [%02x]\t", opcode); \
|
||||
} while (0)
|
||||
#else
|
||||
#define emit_label(opcode) \
|
||||
do { \
|
||||
uint32 label_addr = (uint32)(uintptr_t)handle_table[opcode]; \
|
||||
/* emit uint32 label address in 32-bit target */ \
|
||||
wasm_loader_emit_uint32(loader_ctx, label_addr); \
|
||||
LOG_OP("\nemit_op [%02x]\t", opcode); \
|
||||
} while (0)
|
||||
#endif
|
||||
#define skip_label() \
|
||||
do { \
|
||||
wasm_loader_emit_backspace(loader_ctx, sizeof(int16)); \
|
||||
wasm_loader_emit_backspace(loader_ctx, sizeof(int32)); \
|
||||
LOG_OP("\ndelete last op\n"); \
|
||||
} while (0)
|
||||
#endif /* end of WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS */
|
||||
|
@ -4351,13 +4357,6 @@ preserve_referenced_local(WASMLoaderContext *loader_ctx, uint8 opcode,
|
|||
}
|
||||
|
||||
return true;
|
||||
|
||||
#if WASM_ENABLE_LABELS_AS_VALUES != 0
|
||||
#if WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS == 0
|
||||
fail:
|
||||
return false;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
static bool
|
||||
|
@ -6146,6 +6145,9 @@ re_scan:
|
|||
uint8 ref_type;
|
||||
BranchBlock *cur_block = loader_ctx->frame_csp - 1;
|
||||
int32 available_stack_cell;
|
||||
#if WASM_ENABLE_FAST_INTERP != 0
|
||||
uint8 *p_code_compiled_tmp = loader_ctx->p_code_compiled;
|
||||
#endif
|
||||
|
||||
POP_I32();
|
||||
|
||||
|
@ -6168,26 +6170,26 @@ re_scan:
|
|||
#if WASM_ENABLE_FAST_INTERP != 0
|
||||
if (loader_ctx->p_code_compiled) {
|
||||
uint8 opcode_tmp = WASM_OP_SELECT_64;
|
||||
uint8 *p_code_compiled_tmp =
|
||||
loader_ctx->p_code_compiled - 2;
|
||||
#if WASM_ENABLE_LABELS_AS_VALUES != 0
|
||||
#if WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS != 0
|
||||
*(void **)(p_code_compiled_tmp
|
||||
- sizeof(void *)) =
|
||||
handle_table[opcode_tmp];
|
||||
#else
|
||||
#if UINTPTR_MAX == UINT64_MAX
|
||||
/* emit int32 relative offset in 64-bit target
|
||||
*/
|
||||
int32 offset =
|
||||
(int32)((uint8 *)handle_table[opcode_tmp]
|
||||
- (uint8 *)handle_table[0]);
|
||||
if (!(offset >= INT16_MIN
|
||||
&& offset < INT16_MAX)) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"pre-compiled label offset "
|
||||
"out of range");
|
||||
goto fail;
|
||||
}
|
||||
*(int16 *)(p_code_compiled_tmp
|
||||
- sizeof(int16)) = (int16)offset;
|
||||
*(int32 *)(p_code_compiled_tmp
|
||||
- sizeof(int32)) = offset;
|
||||
#else
|
||||
/* emit uint32 label address in 32-bit target */
|
||||
*(uint32 *)(p_code_compiled_tmp
|
||||
- sizeof(uint32)) =
|
||||
(uint32)(uintptr_t)handle_table[opcode_tmp];
|
||||
#endif
|
||||
#endif /* end of WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS */
|
||||
#else /* else of WASM_ENABLE_LABELS_AS_VALUES */
|
||||
#if WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS != 0
|
||||
|
@ -6263,15 +6265,16 @@ re_scan:
|
|||
*(void **)(p_code_compiled_tmp - sizeof(void *)) =
|
||||
handle_table[opcode_tmp];
|
||||
#else
|
||||
#if UINTPTR_MAX == UINT64_MAX
|
||||
/* emit int32 relative offset in 64-bit target */
|
||||
int32 offset = (int32)((uint8 *)handle_table[opcode_tmp]
|
||||
- (uint8 *)handle_table[0]);
|
||||
if (!(offset >= INT16_MIN && offset < INT16_MAX)) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"pre-compiled label offset out of range");
|
||||
goto fail;
|
||||
}
|
||||
*(int16 *)(p_code_compiled_tmp - sizeof(int16)) =
|
||||
(int16)offset;
|
||||
*(int32 *)(p_code_compiled_tmp - sizeof(int32)) = offset;
|
||||
#else
|
||||
/* emit uint32 label address in 32-bit target */
|
||||
*(uint32 *)(p_code_compiled_tmp - sizeof(uint32)) =
|
||||
(uint32)(uintptr_t)handle_table[opcode_tmp];
|
||||
#endif
|
||||
#endif /* end of WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS */
|
||||
#else /* else of WASM_ENABLE_LABELS_AS_VALUES */
|
||||
#if WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS != 0
|
||||
|
|
Loading…
Reference in New Issue
Block a user