@@ -9713,13 +9713,6 @@ reserve_block_ret(WASMLoaderContext *loader_ctx, uint8 opcode,
97139713 GET_LOCAL_REFTYPE(); \
97149714 } while (0)
97159715
9716- #define CHECK_BR(depth) \
9717- do { \
9718- if (!wasm_loader_check_br(loader_ctx, depth, error_buf, \
9719- error_buf_size)) \
9720- goto fail; \
9721- } while (0)
9722-
97239716static bool
97249717check_memory(WASMModule *module, char *error_buf, uint32 error_buf_size)
97259718{
@@ -9920,6 +9913,27 @@ wasm_loader_check_br(WASMLoaderContext *loader_ctx, uint32 depth,
99209913 bool is_type_multi_byte;
99219914#endif
99229915
9916+ uint8 *frame_ref_old = loader_ctx->frame_ref;
9917+ uint8 *frame_ref_after_popped = NULL;
9918+ uint8 frame_ref_tmp[4] = { 0 };
9919+ uint8 *frame_ref_buf = frame_ref_tmp;
9920+ uint32 stack_cell_num_old = loader_ctx->stack_cell_num;
9921+ #if WASM_ENABLE_GC != 0
9922+ WASMRefTypeMap *frame_reftype_map_old = loader_ctx->frame_reftype_map;
9923+ WASMRefTypeMap *frame_reftype_map_after_popped = NULL;
9924+ WASMRefTypeMap frame_reftype_map_tmp[4] = { 0 };
9925+ WASMRefTypeMap *frame_reftype_map_buf = frame_reftype_map_tmp;
9926+ uint32 reftype_map_num_old = loader_ctx->reftype_map_num;
9927+ #endif
9928+ #if WASM_ENABLE_FAST_INTERP != 0
9929+ int16 *frame_offset_old = loader_ctx->frame_offset;
9930+ int16 *frame_offset_after_popped = NULL;
9931+ int16 frame_offset_tmp[4] = { 0 };
9932+ int16 *frame_offset_buf = frame_offset_tmp;
9933+ uint16 dynamic_offset_old = (loader_ctx->frame_csp - 1)->dynamic_offset;
9934+ #endif
9935+ bool ret = false;
9936+
99239937 bh_assert(loader_ctx->csp_num > 0);
99249938 if (loader_ctx->csp_num - 1 < depth) {
99259939 set_error_buf(error_buf, error_buf_size,
@@ -9956,7 +9970,7 @@ wasm_loader_check_br(WASMLoaderContext *loader_ctx, uint32 depth,
99569970 /* If the stack is in polymorphic state, just clear the stack
99579971 * and then re-push the values to make the stack top values
99589972 * match block type. */
9959- if (cur_block->is_stack_polymorphic && !is_br_table ) {
9973+ if (cur_block->is_stack_polymorphic) {
99609974#if WASM_ENABLE_GC != 0
99619975 int32 j = reftype_map_count - 1;
99629976#endif
@@ -9975,6 +9989,52 @@ wasm_loader_check_br(WASMLoaderContext *loader_ctx, uint32 depth,
99759989#endif
99769990 POP_TYPE(types[i]);
99779991 }
9992+
9993+ /* Backup stack data since it may be changed in the below
9994+ push operations, and the stack data may be used when
9995+ checking other target blocks of opcode br_table */
9996+ if (is_br_table) {
9997+ uint64 total_size;
9998+
9999+ frame_ref_after_popped = loader_ctx->frame_ref;
10000+ total_size = (uint64)sizeof(uint8)
10001+ * (frame_ref_old - frame_ref_after_popped);
10002+ if (total_size > sizeof(frame_ref_tmp)
10003+ && !(frame_ref_buf = loader_malloc(total_size, error_buf,
10004+ error_buf_size))) {
10005+ goto fail;
10006+ }
10007+ bh_memcpy_s(frame_ref_buf, (uint32)total_size,
10008+ frame_ref_after_popped, (uint32)total_size);
10009+
10010+ #if WASM_ENABLE_GC != 0
10011+ frame_reftype_map_after_popped = loader_ctx->frame_reftype_map;
10012+ total_size =
10013+ (uint64)sizeof(WASMRefTypeMap)
10014+ * (frame_reftype_map_old - frame_reftype_map_after_popped);
10015+ if (total_size > sizeof(frame_reftype_map_tmp)
10016+ && !(frame_reftype_map_buf = loader_malloc(
10017+ total_size, error_buf, error_buf_size))) {
10018+ goto fail;
10019+ }
10020+ bh_memcpy_s(frame_reftype_map_buf, (uint32)total_size,
10021+ frame_reftype_map_after_popped, (uint32)total_size);
10022+ #endif
10023+
10024+ #if WASM_ENABLE_FAST_INTERP != 0
10025+ frame_offset_after_popped = loader_ctx->frame_offset;
10026+ total_size = (uint64)sizeof(int16)
10027+ * (frame_offset_old - frame_offset_after_popped);
10028+ if (total_size > sizeof(frame_offset_tmp)
10029+ && !(frame_offset_buf = loader_malloc(total_size, error_buf,
10030+ error_buf_size))) {
10031+ goto fail;
10032+ }
10033+ bh_memcpy_s(frame_offset_buf, (uint32)total_size,
10034+ frame_offset_after_popped, (uint32)total_size);
10035+ #endif
10036+ }
10037+
997810038#if WASM_ENABLE_GC != 0
997910039 j = 0;
998010040#endif
@@ -9995,7 +10055,55 @@ wasm_loader_check_br(WASMLoaderContext *loader_ctx, uint32 depth,
999510055#endif
999610056 PUSH_TYPE(types[i]);
999710057 }
9998- return true;
10058+
10059+ #if WASM_ENABLE_FAST_INTERP != 0
10060+ emit_br_info(target_block);
10061+ #endif
10062+
10063+ /* Restore the stack data, note that frame_ref_bottom,
10064+ frame_reftype_map_bottom, frame_offset_bottom may be
10065+ re-allocated in the above push operations */
10066+ if (is_br_table) {
10067+ uint32 total_size;
10068+
10069+ /* The stack operand num should not be smaller than before
10070+ after pop and push operations */
10071+ bh_assert(loader_ctx->stack_cell_num >= stack_cell_num_old);
10072+ loader_ctx->stack_cell_num = stack_cell_num_old;
10073+ loader_ctx->frame_ref =
10074+ loader_ctx->frame_ref_bottom + stack_cell_num_old;
10075+ total_size = (uint32)sizeof(uint8)
10076+ * (frame_ref_old - frame_ref_after_popped);
10077+ bh_memcpy_s((uint8 *)loader_ctx->frame_ref - total_size, total_size,
10078+ frame_ref_buf, total_size);
10079+
10080+ #if WASM_ENABLE_GC != 0
10081+ /* The stack operand num should not be smaller than before
10082+ after pop and push operations */
10083+ bh_assert(loader_ctx->reftype_map_num >= reftype_map_num_old);
10084+ loader_ctx->reftype_map_num = reftype_map_num_old;
10085+ loader_ctx->frame_reftype_map =
10086+ loader_ctx->frame_reftype_map_bottom + reftype_map_num_old;
10087+ total_size =
10088+ (uint32)sizeof(WASMRefTypeMap)
10089+ * (frame_reftype_map_old - frame_reftype_map_after_popped);
10090+ bh_memcpy_s((uint8 *)loader_ctx->frame_reftype_map - total_size,
10091+ total_size, frame_reftype_map_buf, total_size);
10092+ #endif
10093+
10094+ #if WASM_ENABLE_FAST_INTERP != 0
10095+ loader_ctx->frame_offset =
10096+ loader_ctx->frame_offset_bottom + stack_cell_num_old;
10097+ total_size = (uint32)sizeof(int16)
10098+ * (frame_offset_old - frame_offset_after_popped);
10099+ bh_memcpy_s((uint8 *)loader_ctx->frame_offset - total_size,
10100+ total_size, frame_offset_buf, total_size);
10101+ (loader_ctx->frame_csp - 1)->dynamic_offset = dynamic_offset_old;
10102+ #endif
10103+ }
10104+
10105+ ret = true;
10106+ goto cleanup_and_return;
999910107 }
1000010108
1000110109 available_stack_cell =
@@ -10031,7 +10139,7 @@ wasm_loader_check_br(WASMLoaderContext *loader_ctx, uint32 depth,
1003110139 ref_type,
1003210140#endif
1003310141 error_buf, error_buf_size)) {
10034- return false ;
10142+ goto fail ;
1003510143 }
1003610144 cell_num = wasm_value_type_cell_num(types[i]);
1003710145 frame_ref -= cell_num;
@@ -10045,10 +10153,26 @@ wasm_loader_check_br(WASMLoaderContext *loader_ctx, uint32 depth,
1004510153#endif
1004610154 }
1004710155
10048- return true;
10156+ #if WASM_ENABLE_FAST_INTERP != 0
10157+ emit_br_info(target_block);
10158+ #endif
1004910159
10160+ ret = true;
10161+
10162+ cleanup_and_return:
1005010163fail:
10051- return false;
10164+ if (frame_ref_buf && frame_ref_buf != frame_ref_tmp)
10165+ wasm_runtime_free(frame_ref_buf);
10166+ #if WASM_ENABLE_GC != 0
10167+ if (frame_reftype_map_buf && frame_reftype_map_buf != frame_reftype_map_tmp)
10168+ wasm_runtime_free(frame_reftype_map_buf);
10169+ #endif
10170+ #if WASM_ENABLE_FAST_INTERP != 0
10171+ if (frame_offset_buf && frame_offset_buf != frame_offset_tmp)
10172+ wasm_runtime_free(frame_offset_tmp);
10173+ #endif
10174+
10175+ return ret;
1005210176}
1005310177
1005410178static BranchBlock *
@@ -10066,9 +10190,6 @@ check_branch_block(WASMLoaderContext *loader_ctx, uint8 **p_buf, uint8 *buf_end,
1006610190 }
1006710191
1006810192 frame_csp_tmp = loader_ctx->frame_csp - depth - 1;
10069- #if WASM_ENABLE_FAST_INTERP != 0
10070- emit_br_info(frame_csp_tmp);
10071- #endif
1007210193
1007310194 *p_buf = p;
1007410195 return frame_csp_tmp;
0 commit comments