Skip to content

Commit 4bfcbc2

Browse files
fix problem about local in fast-interp (#406)
1 parent c59bfe2 commit 4bfcbc2

File tree

3 files changed

+122
-8
lines changed

3 files changed

+122
-8
lines changed

core/iwasm/interpreter/wasm_loader.c

Lines changed: 60 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4273,24 +4273,30 @@ preserve_referenced_local(WASMLoaderContext *loader_ctx, uint8 opcode,
42734273
uint32 local_index, uint32 local_type, bool *preserved,
42744274
char *error_buf, uint32 error_buf_size)
42754275
{
4276+
uint32 i = 0;
42764277
int16 preserved_offset = (int16)local_index;
4278+
42774279
*preserved = false;
4278-
for (uint32 i = 0; i < loader_ctx->stack_cell_num; i++) {
4280+
while (i < loader_ctx->stack_cell_num) {
4281+
uint8 cur_type = loader_ctx->frame_ref_bottom[i];
4282+
42794283
/* move previous local into dynamic space before a set/tee_local opcode */
42804284
if (loader_ctx->frame_offset_bottom[i] == (int16)local_index) {
4281-
if (preserved_offset == (int16)local_index) {
4285+
if (!(*preserved)) {
42824286
*preserved = true;
42834287
skip_label();
4288+
preserved_offset = loader_ctx->preserved_local_offset;
4289+
if (loader_ctx->p_code_compiled) {
4290+
bh_assert(preserved_offset != (int16)local_index);
4291+
}
42844292
if (local_type == VALUE_TYPE_I32
42854293
|| local_type == VALUE_TYPE_F32) {
4286-
preserved_offset = loader_ctx->preserved_local_offset;
42874294
/* Only increase preserve offset in the second traversal */
42884295
if (loader_ctx->p_code_compiled)
42894296
loader_ctx->preserved_local_offset++;
42904297
emit_label(EXT_OP_COPY_STACK_TOP);
42914298
}
42924299
else {
4293-
preserved_offset = loader_ctx->preserved_local_offset;
42944300
if (loader_ctx->p_code_compiled)
42954301
loader_ctx->preserved_local_offset += 2;
42964302
emit_label(EXT_OP_COPY_STACK_TOP_I64);
@@ -4301,6 +4307,11 @@ preserve_referenced_local(WASMLoaderContext *loader_ctx, uint8 opcode,
43014307
}
43024308
loader_ctx->frame_offset_bottom[i] = preserved_offset;
43034309
}
4310+
4311+
if (cur_type == VALUE_TYPE_I32 || cur_type == VALUE_TYPE_F32)
4312+
i++;
4313+
else
4314+
i += 2;
43044315
}
43054316

43064317
return true;
@@ -4311,6 +4322,38 @@ preserve_referenced_local(WASMLoaderContext *loader_ctx, uint8 opcode,
43114322
#endif
43124323
}
43134324

4325+
static bool
4326+
preserve_local_for_block(WASMLoaderContext *loader_ctx, uint8 opcode,
4327+
char *error_buf, uint32 error_buf_size)
4328+
{
4329+
uint32 i = 0;
4330+
bool preserve_local;
4331+
4332+
/* preserve locals before blocks to ensure that "tee/set_local" inside
4333+
blocks will not influence the value of these locals */
4334+
while (i < loader_ctx->stack_cell_num) {
4335+
int16 cur_offset = loader_ctx->frame_offset_bottom[i];
4336+
uint8 cur_type = loader_ctx->frame_ref_bottom[i];
4337+
4338+
if ((cur_offset < loader_ctx->start_dynamic_offset)
4339+
&& (cur_offset >= 0)) {
4340+
if (!(preserve_referenced_local(loader_ctx, opcode, cur_offset,
4341+
cur_type, &preserve_local,
4342+
error_buf, error_buf_size)))
4343+
return false;
4344+
}
4345+
4346+
if (cur_type == VALUE_TYPE_I32 || cur_type == VALUE_TYPE_F32) {
4347+
i++;
4348+
}
4349+
else {
4350+
i += 2;
4351+
}
4352+
}
4353+
4354+
return true;
4355+
}
4356+
43144357
static bool
43154358
add_label_patch_to_list(BranchBlock *frame_csp,
43164359
uint8 patch_type, uint8 *p_code_compiled,
@@ -5387,6 +5430,13 @@ copy_params_to_dynamic_space(WASMLoaderContext *loader_ctx, bool is_if_block,
53875430
#define BLOCK_HAS_PARAM(block_type) \
53885431
(!block_type.is_value_type && block_type.u.type->param_count > 0)
53895432

5433+
#define PRESERVE_LOCAL_FOR_BLOCK() do { \
5434+
if (!(preserve_local_for_block(loader_ctx, opcode, \
5435+
error_buf, error_buf_size))) { \
5436+
goto fail; \
5437+
} \
5438+
} while (0)
5439+
53905440
static bool
53915441
wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func,
53925442
BlockAddr *block_addr_cache,
@@ -5475,10 +5525,16 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func,
54755525
break;
54765526

54775527
case WASM_OP_IF:
5528+
#if WASM_ENABLE_FAST_INTERP != 0
5529+
PRESERVE_LOCAL_FOR_BLOCK();
5530+
#endif
54785531
POP_I32();
54795532
goto handle_op_block_and_loop;
54805533
case WASM_OP_BLOCK:
54815534
case WASM_OP_LOOP:
5535+
#if WASM_ENABLE_FAST_INTERP != 0
5536+
PRESERVE_LOCAL_FOR_BLOCK();
5537+
#endif
54825538
handle_op_block_and_loop:
54835539
{
54845540
uint8 value_type;

core/iwasm/interpreter/wasm_mini_loader.c

Lines changed: 60 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3172,24 +3172,30 @@ preserve_referenced_local(WASMLoaderContext *loader_ctx, uint8 opcode,
31723172
uint32 local_index, uint32 local_type, bool *preserved,
31733173
char *error_buf, uint32 error_buf_size)
31743174
{
3175+
uint32 i = 0;
31753176
int16 preserved_offset = (int16)local_index;
3177+
31763178
*preserved = false;
3177-
for (uint32 i = 0; i < loader_ctx->stack_cell_num; i++) {
3179+
while (i < loader_ctx->stack_cell_num) {
3180+
uint8 cur_type = loader_ctx->frame_ref_bottom[i];
3181+
31783182
/* move previous local into dynamic space before a set/tee_local opcode */
31793183
if (loader_ctx->frame_offset_bottom[i] == (int16)local_index) {
3180-
if (preserved_offset == (int16)local_index) {
3184+
if (!(*preserved)) {
31813185
*preserved = true;
31823186
skip_label();
3187+
preserved_offset = loader_ctx->preserved_local_offset;
3188+
if (loader_ctx->p_code_compiled) {
3189+
bh_assert(preserved_offset != (int16)local_index);
3190+
}
31833191
if (local_type == VALUE_TYPE_I32
31843192
|| local_type == VALUE_TYPE_F32) {
3185-
preserved_offset = loader_ctx->preserved_local_offset;
31863193
/* Only increase preserve offset in the second traversal */
31873194
if (loader_ctx->p_code_compiled)
31883195
loader_ctx->preserved_local_offset++;
31893196
emit_label(EXT_OP_COPY_STACK_TOP);
31903197
}
31913198
else {
3192-
preserved_offset = loader_ctx->preserved_local_offset;
31933199
if (loader_ctx->p_code_compiled)
31943200
loader_ctx->preserved_local_offset += 2;
31953201
emit_label(EXT_OP_COPY_STACK_TOP_I64);
@@ -3200,6 +3206,11 @@ preserve_referenced_local(WASMLoaderContext *loader_ctx, uint8 opcode,
32003206
}
32013207
loader_ctx->frame_offset_bottom[i] = preserved_offset;
32023208
}
3209+
3210+
if (cur_type == VALUE_TYPE_I32 || cur_type == VALUE_TYPE_F32)
3211+
i++;
3212+
else
3213+
i += 2;
32033214
}
32043215

32053216
return true;
@@ -3210,6 +3221,38 @@ preserve_referenced_local(WASMLoaderContext *loader_ctx, uint8 opcode,
32103221
#endif
32113222
}
32123223

3224+
static bool
3225+
preserve_local_for_block(WASMLoaderContext *loader_ctx, uint8 opcode,
3226+
char *error_buf, uint32 error_buf_size)
3227+
{
3228+
uint32 i = 0;
3229+
bool preserve_local;
3230+
3231+
/* preserve locals before blocks to ensure that "tee/set_local" inside
3232+
blocks will not influence the value of these locals */
3233+
while (i < loader_ctx->stack_cell_num) {
3234+
int16 cur_offset = loader_ctx->frame_offset_bottom[i];
3235+
uint8 cur_type = loader_ctx->frame_ref_bottom[i];
3236+
3237+
if ((cur_offset < loader_ctx->start_dynamic_offset)
3238+
&& (cur_offset >= 0)) {
3239+
if (!(preserve_referenced_local(loader_ctx, opcode, cur_offset,
3240+
cur_type, &preserve_local,
3241+
error_buf, error_buf_size)))
3242+
return false;
3243+
}
3244+
3245+
if (cur_type == VALUE_TYPE_I32 || cur_type == VALUE_TYPE_F32) {
3246+
i++;
3247+
}
3248+
else {
3249+
i += 2;
3250+
}
3251+
}
3252+
3253+
return true;
3254+
}
3255+
32133256
static bool
32143257
add_label_patch_to_list(BranchBlock *frame_csp,
32153258
uint8 patch_type, uint8 *p_code_compiled,
@@ -4218,6 +4261,13 @@ copy_params_to_dynamic_space(WASMLoaderContext *loader_ctx, bool is_if_block,
42184261
#define BLOCK_HAS_PARAM(block_type) \
42194262
(!block_type.is_value_type && block_type.u.type->param_count > 0)
42204263

4264+
#define PRESERVE_LOCAL_FOR_BLOCK() do { \
4265+
if (!(preserve_local_for_block(loader_ctx, opcode, \
4266+
error_buf, error_buf_size))) { \
4267+
goto fail; \
4268+
} \
4269+
} while (0)
4270+
42214271
static bool
42224272
wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func,
42234273
BlockAddr *block_addr_cache,
@@ -4306,10 +4356,16 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func,
43064356
break;
43074357

43084358
case WASM_OP_IF:
4359+
#if WASM_ENABLE_FAST_INTERP != 0
4360+
PRESERVE_LOCAL_FOR_BLOCK();
4361+
#endif
43094362
POP_I32();
43104363
goto handle_op_block_and_loop;
43114364
case WASM_OP_BLOCK:
43124365
case WASM_OP_LOOP:
4366+
#if WASM_ENABLE_FAST_INTERP != 0
4367+
PRESERVE_LOCAL_FOR_BLOCK();
4368+
#endif
43134369
handle_op_block_and_loop:
43144370
{
43154371
uint8 value_type;

wamr-compiler/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ else()
1010
enable_language (ASM_MASM)
1111
endif()
1212

13+
set (CMAKE_CXX_STANDARD 14)
14+
1315
if (NOT DEFINED WAMR_BUILD_PLATFORM)
1416
set (WAMR_BUILD_PLATFORM "linux")
1517
endif()

0 commit comments

Comments
 (0)