Skip to content

Commit 0feae05

Browse files
authored
wasm loader: Fix several issues in GC and exception handling (bytecodealliance#3586)
Fix several issues of GC and exception handling in wasm loader: - Should restore param_reftype_maps/param_reftype_map_count/param_count in the handling of opcode throw - Should set wasm_ref_type when pushing param types of tag type and block type if the type is a multi-byte type - Should set init_values.data as NULL for opcode struct.new_default in load_init_expr This PR fixes the issues reported in bytecodealliance#3411.
1 parent 7771212 commit 0feae05

File tree

1 file changed

+51
-15
lines changed

1 file changed

+51
-15
lines changed

core/iwasm/interpreter/wasm_loader.c

Lines changed: 51 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1039,6 +1039,7 @@ load_init_expr(WASMModule *module, const uint8 **p_buf, const uint8 *buf_end,
10391039
}
10401040

10411041
cur_value.type_index = type_idx;
1042+
cur_value.data = NULL;
10421043
wasm_set_refheaptype_typeidx(
10431044
&cur_ref_type.ref_ht_typeidx, false, type_idx);
10441045
if (!push_const_expr_stack(
@@ -11201,10 +11202,15 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func,
1120111202

1120211203
/* Pass parameters to block */
1120311204
if (BLOCK_HAS_PARAM(block_type)) {
11204-
for (i = 0; i < block_type.u.type->param_count; i++) {
11205+
WASMFuncType *func_type = block_type.u.type;
11206+
#if WASM_ENABLE_GC != 0
11207+
WASMRefType *ref_type;
11208+
uint32 j = 0;
11209+
#endif
11210+
for (i = 0; i < func_type->param_count; i++) {
1120511211
#if WASM_ENABLE_FAST_INTERP != 0
11206-
uint32 cell_num = wasm_value_type_cell_num(
11207-
block_type.u.type->types[i]);
11212+
uint32 cell_num =
11213+
wasm_value_type_cell_num(func_type->types[i]);
1120811214
if (i >= available_params) {
1120911215
/* If there isn't enough data on stack, push a dummy
1121011216
* offset to keep the stack consistent with
@@ -11228,7 +11234,17 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func,
1122811234
loader_ctx->frame_offset += cell_num;
1122911235
}
1123011236
#endif
11231-
PUSH_TYPE(block_type.u.type->types[i]);
11237+
#if WASM_ENABLE_GC != 0
11238+
if (wasm_is_type_multi_byte_type(func_type->types[i])) {
11239+
bh_assert(func_type->ref_type_maps[j].index == i);
11240+
ref_type = func_type->ref_type_maps[j].ref_type;
11241+
bh_memcpy_s(&wasm_ref_type, sizeof(WASMRefType),
11242+
ref_type,
11243+
wasm_reftype_struct_size(ref_type));
11244+
j++;
11245+
}
11246+
#endif
11247+
PUSH_TYPE(func_type->types[i]);
1123211248
}
1123311249
}
1123411250

@@ -11356,6 +11372,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func,
1135611372
int32 available_stack_cell =
1135711373
(int32)(loader_ctx->stack_cell_num
1135811374
- cur_block->stack_cell_num);
11375+
int32 tti;
1135911376

1136011377
/* Check stack values match return types by comparing tag param
1136111378
* types with stack cells */
@@ -11364,19 +11381,21 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func,
1136411381
WASMRefTypeMap *frame_reftype_map =
1136511382
loader_ctx->frame_reftype_map;
1136611383
uint32 frame_reftype_map_num = loader_ctx->reftype_map_num;
11384+
11385+
/* Temporarily set these values since they may be used in
11386+
GET_LOCAL_REFTYPE(), remember they must be restored later */
1136711387
param_reftype_maps = tag_type->ref_type_maps;
1136811388
/* For tag_type function, it shouldn't have result_count = 0 */
1136911389
param_reftype_map_count = tag_type->ref_type_map_count;
11370-
param_count = (int32)tag_type->param_count;
11390+
param_count = tag_type->param_count;
1137111391
#endif
1137211392

11373-
for (int tti = (int32)tag_type->param_count - 1; tti >= 0;
11374-
tti--) {
11393+
for (tti = (int32)tag_type->param_count - 1; tti >= 0; tti--) {
1137511394
#if WASM_ENABLE_GC != 0
1137611395
local_type = tag_type->types[tti];
1137711396
local_idx = tti;
1137811397
/* Get the wasm_ref_type if the local_type is multibyte
11379-
* type */
11398+
type */
1138011399
GET_LOCAL_REFTYPE();
1138111400
#endif
1138211401

@@ -11406,6 +11425,13 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func,
1140611425
wasm_value_type_cell_num(tag_type->types[tti]);
1140711426
}
1140811427

11428+
#if WASM_ENABLE_GC != 0
11429+
/* Restore the values */
11430+
param_reftype_maps = func->func_type->ref_type_maps;
11431+
param_reftype_map_count = func->func_type->ref_type_map_count;
11432+
param_count = func->func_type->param_count;
11433+
#endif
11434+
1140911435
/* throw is stack polymorphic */
1141011436
(void)label_type;
1141111437
RESET_STACK();
@@ -11497,10 +11523,6 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func,
1149711523
goto fail;
1149811524
}
1149911525

11500-
BlockType new_block_type;
11501-
new_block_type.is_value_type = false;
11502-
new_block_type.u.type = func_type;
11503-
1150411526
/*
1150511527
* replace frame_csp by LABEL_TYPE_CATCH
1150611528
*/
@@ -11510,10 +11532,24 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func,
1151011532
* CATCH Blocks */
1151111533
RESET_STACK();
1151211534

11535+
#if WASM_ENABLE_GC != 0
11536+
WASMRefType *ref_type;
11537+
uint32 j = 0;
11538+
#endif
11539+
1151311540
/* push types on the stack according to caught type */
11514-
if (BLOCK_HAS_PARAM(new_block_type)) {
11515-
for (i = 0; i < new_block_type.u.type->param_count; i++)
11516-
PUSH_TYPE(new_block_type.u.type->types[i]);
11541+
for (i = 0; i < func_type->param_count; i++) {
11542+
#if WASM_ENABLE_GC != 0
11543+
if (wasm_is_type_multi_byte_type(func_type->types[i])) {
11544+
bh_assert(func_type->ref_type_maps[j].index == i);
11545+
ref_type = func_type->ref_type_maps[j].ref_type;
11546+
bh_memcpy_s(&wasm_ref_type, sizeof(WASMRefType),
11547+
ref_type,
11548+
wasm_reftype_struct_size(ref_type));
11549+
j++;
11550+
}
11551+
#endif
11552+
PUSH_TYPE(func_type->types[i]);
1151711553
}
1151811554
break;
1151911555
}

0 commit comments

Comments
 (0)