Forráskód Böngészése

Fix dynamic offset not updated in op_br for block with ret type (#3269)

The PR #3259 reverted PR #3192, it fixes #3210 but makes #3170 failed again.

The workaround is that we should update `ctx->dynamic_offset` only for opcode br
and should not update it for opcode br_if. This PR fixes both issue #3170 and #3210.
Wenyong Huang 1 éve
szülő
commit
6ee71000f9

+ 23 - 21
core/iwasm/interpreter/wasm_loader.c

@@ -8448,11 +8448,11 @@ fail:
         wasm_loader_emit_ptr(loader_ctx, NULL);                              \
         wasm_loader_emit_ptr(loader_ctx, NULL);                              \
     } while (0)
     } while (0)
 
 
-#define emit_br_info(frame_csp)                                         \
-    do {                                                                \
-        if (!wasm_loader_emit_br_info(loader_ctx, frame_csp, error_buf, \
-                                      error_buf_size))                  \
-            goto fail;                                                  \
+#define emit_br_info(frame_csp, is_br)                                         \
+    do {                                                                       \
+        if (!wasm_loader_emit_br_info(loader_ctx, frame_csp, is_br, error_buf, \
+                                      error_buf_size))                         \
+            goto fail;                                                         \
     } while (0)
     } while (0)
 
 
 #define LAST_OP_OUTPUT_I32()                                                   \
 #define LAST_OP_OUTPUT_I32()                                                   \
@@ -8846,7 +8846,7 @@ apply_label_patch(WASMLoaderContext *ctx, uint8 depth, uint8 patch_type)
 
 
 static bool
 static bool
 wasm_loader_emit_br_info(WASMLoaderContext *ctx, BranchBlock *frame_csp,
 wasm_loader_emit_br_info(WASMLoaderContext *ctx, BranchBlock *frame_csp,
-                         char *error_buf, uint32 error_buf_size)
+                         bool is_br, char *error_buf, uint32 error_buf_size)
 {
 {
     /* br info layout:
     /* br info layout:
      *  a) arity of target block
      *  a) arity of target block
@@ -8907,6 +8907,8 @@ wasm_loader_emit_br_info(WASMLoaderContext *ctx, BranchBlock *frame_csp,
         /* Part e */
         /* Part e */
         dynamic_offset =
         dynamic_offset =
             frame_csp->dynamic_offset + wasm_get_cell_num(types, arity);
             frame_csp->dynamic_offset + wasm_get_cell_num(types, arity);
+        if (is_br)
+            ctx->dynamic_offset = dynamic_offset;
         for (i = (int32)arity - 1; i >= 0; i--) {
         for (i = (int32)arity - 1; i >= 0; i--) {
             cell = (uint8)wasm_value_type_cell_num(types[i]);
             cell = (uint8)wasm_value_type_cell_num(types[i]);
             dynamic_offset -= cell;
             dynamic_offset -= cell;
@@ -9774,8 +9776,8 @@ check_memory_align_equal(uint8 opcode, uint32 align, char *error_buf,
 #endif /* end of WASM_ENABLE_SHARED_MEMORY */
 #endif /* end of WASM_ENABLE_SHARED_MEMORY */
 
 
 static bool
 static bool
-wasm_loader_check_br(WASMLoaderContext *loader_ctx, uint32 depth,
-                     bool is_br_table, char *error_buf, uint32 error_buf_size)
+wasm_loader_check_br(WASMLoaderContext *loader_ctx, uint32 depth, uint8 opcode,
+                     char *error_buf, uint32 error_buf_size)
 {
 {
     BranchBlock *target_block, *cur_block;
     BranchBlock *target_block, *cur_block;
     BlockType *target_block_type;
     BlockType *target_block_type;
@@ -9872,7 +9874,7 @@ wasm_loader_check_br(WASMLoaderContext *loader_ctx, uint32 depth,
         /* Backup stack data since it may be changed in the below
         /* Backup stack data since it may be changed in the below
            push operations, and the stack data may be used when
            push operations, and the stack data may be used when
            checking other target blocks of opcode br_table */
            checking other target blocks of opcode br_table */
-        if (is_br_table) {
+        if (opcode == WASM_OP_BR_TABLE) {
             uint64 total_size;
             uint64 total_size;
 
 
             frame_ref_after_popped = loader_ctx->frame_ref;
             frame_ref_after_popped = loader_ctx->frame_ref;
@@ -9936,13 +9938,13 @@ wasm_loader_check_br(WASMLoaderContext *loader_ctx, uint32 depth,
         }
         }
 
 
 #if WASM_ENABLE_FAST_INTERP != 0
 #if WASM_ENABLE_FAST_INTERP != 0
-        emit_br_info(target_block);
+        emit_br_info(target_block, opcode == WASM_OP_BR);
 #endif
 #endif
 
 
         /* Restore the stack data, note that frame_ref_bottom,
         /* Restore the stack data, note that frame_ref_bottom,
            frame_reftype_map_bottom, frame_offset_bottom may be
            frame_reftype_map_bottom, frame_offset_bottom may be
            re-allocated in the above push operations */
            re-allocated in the above push operations */
-        if (is_br_table) {
+        if (opcode == WASM_OP_BR_TABLE) {
             uint32 total_size;
             uint32 total_size;
 
 
             /* The stack operand num should not be smaller than before
             /* The stack operand num should not be smaller than before
@@ -10033,7 +10035,7 @@ wasm_loader_check_br(WASMLoaderContext *loader_ctx, uint32 depth,
     }
     }
 
 
 #if WASM_ENABLE_FAST_INTERP != 0
 #if WASM_ENABLE_FAST_INTERP != 0
-    emit_br_info(target_block);
+    emit_br_info(target_block, opcode == WASM_OP_BR);
 #endif
 #endif
 
 
     ret = true;
     ret = true;
@@ -10056,14 +10058,14 @@ fail:
 
 
 static BranchBlock *
 static BranchBlock *
 check_branch_block(WASMLoaderContext *loader_ctx, uint8 **p_buf, uint8 *buf_end,
 check_branch_block(WASMLoaderContext *loader_ctx, uint8 **p_buf, uint8 *buf_end,
-                   bool is_br_table, char *error_buf, uint32 error_buf_size)
+                   uint8 opcode, char *error_buf, uint32 error_buf_size)
 {
 {
     uint8 *p = *p_buf, *p_end = buf_end;
     uint8 *p = *p_buf, *p_end = buf_end;
     BranchBlock *frame_csp_tmp;
     BranchBlock *frame_csp_tmp;
     uint32 depth;
     uint32 depth;
 
 
     read_leb_uint32(p, p_end, depth);
     read_leb_uint32(p, p_end, depth);
-    if (!wasm_loader_check_br(loader_ctx, depth, is_br_table, error_buf,
+    if (!wasm_loader_check_br(loader_ctx, depth, opcode, error_buf,
                               error_buf_size)) {
                               error_buf_size)) {
         goto fail;
         goto fail;
     }
     }
@@ -10980,7 +10982,7 @@ re_scan:
 
 
                 /* check the target catching block:  LABEL_TYPE_CATCH */
                 /* check the target catching block:  LABEL_TYPE_CATCH */
                 if (!(frame_csp_tmp =
                 if (!(frame_csp_tmp =
-                          check_branch_block(loader_ctx, &p, p_end, false,
+                          check_branch_block(loader_ctx, &p, p_end, opcode,
                                              error_buf, error_buf_size)))
                                              error_buf, error_buf_size)))
                     goto fail;
                     goto fail;
 
 
@@ -11267,7 +11269,7 @@ re_scan:
             case WASM_OP_BR:
             case WASM_OP_BR:
             {
             {
                 if (!(frame_csp_tmp =
                 if (!(frame_csp_tmp =
-                          check_branch_block(loader_ctx, &p, p_end, false,
+                          check_branch_block(loader_ctx, &p, p_end, opcode,
                                              error_buf, error_buf_size)))
                                              error_buf, error_buf_size)))
                     goto fail;
                     goto fail;
 
 
@@ -11281,7 +11283,7 @@ re_scan:
                 POP_I32();
                 POP_I32();
 
 
                 if (!(frame_csp_tmp =
                 if (!(frame_csp_tmp =
-                          check_branch_block(loader_ctx, &p, p_end, false,
+                          check_branch_block(loader_ctx, &p, p_end, opcode,
                                              error_buf, error_buf_size)))
                                              error_buf, error_buf_size)))
                     goto fail;
                     goto fail;
 
 
@@ -11351,7 +11353,7 @@ re_scan:
                     }
                     }
 
 
                     if (!(frame_csp_tmp =
                     if (!(frame_csp_tmp =
-                              check_branch_block(loader_ctx, &p, p_end, true,
+                              check_branch_block(loader_ctx, &p, p_end, opcode,
                                                  error_buf, error_buf_size))) {
                                                  error_buf, error_buf_size))) {
                         goto fail;
                         goto fail;
                     }
                     }
@@ -12256,7 +12258,7 @@ re_scan:
 
 
                 if (opcode == WASM_OP_BR_ON_NULL) {
                 if (opcode == WASM_OP_BR_ON_NULL) {
                     if (!(frame_csp_tmp =
                     if (!(frame_csp_tmp =
-                              check_branch_block(loader_ctx, &p, p_end, false,
+                              check_branch_block(loader_ctx, &p, p_end, opcode,
                                                  error_buf, error_buf_size))) {
                                                  error_buf, error_buf_size))) {
                         goto fail;
                         goto fail;
                     }
                     }
@@ -12303,7 +12305,7 @@ re_scan:
                     PUSH_REF(type);
                     PUSH_REF(type);
                 }
                 }
                 if (!(frame_csp_tmp =
                 if (!(frame_csp_tmp =
-                          check_branch_block(loader_ctx, &p, p_end, false,
+                          check_branch_block(loader_ctx, &p, p_end, opcode,
                                              error_buf, error_buf_size))) {
                                              error_buf, error_buf_size))) {
                     goto fail;
                     goto fail;
                 }
                 }
@@ -13785,7 +13787,7 @@ re_scan:
                         }
                         }
                         PUSH_REF(type_tmp);
                         PUSH_REF(type_tmp);
                         if (!(frame_csp_tmp = check_branch_block(
                         if (!(frame_csp_tmp = check_branch_block(
-                                  loader_ctx, &p, p_end, false, error_buf,
+                                  loader_ctx, &p, p_end, opcode, error_buf,
                                   error_buf_size))) {
                                   error_buf_size))) {
                             goto fail;
                             goto fail;
                         }
                         }

+ 19 - 17
core/iwasm/interpreter/wasm_mini_loader.c

@@ -4260,11 +4260,11 @@ wasm_loader_pop_frame_csp(WASMLoaderContext *ctx, char *error_buf,
         wasm_loader_emit_ptr(loader_ctx, NULL);                              \
         wasm_loader_emit_ptr(loader_ctx, NULL);                              \
     } while (0)
     } while (0)
 
 
-#define emit_br_info(frame_csp)                                         \
-    do {                                                                \
-        if (!wasm_loader_emit_br_info(loader_ctx, frame_csp, error_buf, \
-                                      error_buf_size))                  \
-            goto fail;                                                  \
+#define emit_br_info(frame_csp, is_br)                                         \
+    do {                                                                       \
+        if (!wasm_loader_emit_br_info(loader_ctx, frame_csp, is_br, error_buf, \
+                                      error_buf_size))                         \
+            goto fail;                                                         \
     } while (0)
     } while (0)
 
 
 #define LAST_OP_OUTPUT_I32()                                                   \
 #define LAST_OP_OUTPUT_I32()                                                   \
@@ -4649,7 +4649,7 @@ apply_label_patch(WASMLoaderContext *ctx, uint8 depth, uint8 patch_type)
 
 
 static bool
 static bool
 wasm_loader_emit_br_info(WASMLoaderContext *ctx, BranchBlock *frame_csp,
 wasm_loader_emit_br_info(WASMLoaderContext *ctx, BranchBlock *frame_csp,
-                         char *error_buf, uint32 error_buf_size)
+                         bool is_br, char *error_buf, uint32 error_buf_size)
 {
 {
     /* br info layout:
     /* br info layout:
      *  a) arity of target block
      *  a) arity of target block
@@ -4698,6 +4698,8 @@ wasm_loader_emit_br_info(WASMLoaderContext *ctx, BranchBlock *frame_csp,
         /* Part e */
         /* Part e */
         dynamic_offset =
         dynamic_offset =
             frame_csp->dynamic_offset + wasm_get_cell_num(types, arity);
             frame_csp->dynamic_offset + wasm_get_cell_num(types, arity);
+        if (is_br)
+            ctx->dynamic_offset = dynamic_offset;
         for (i = (int32)arity - 1; i >= 0; i--) {
         for (i = (int32)arity - 1; i >= 0; i--) {
             cell = (uint8)wasm_value_type_cell_num(types[i]);
             cell = (uint8)wasm_value_type_cell_num(types[i]);
             dynamic_offset -= cell;
             dynamic_offset -= cell;
@@ -5382,8 +5384,8 @@ fail:
     } while (0)
     } while (0)
 
 
 static bool
 static bool
-wasm_loader_check_br(WASMLoaderContext *loader_ctx, uint32 depth,
-                     bool is_br_table, char *error_buf, uint32 error_buf_size)
+wasm_loader_check_br(WASMLoaderContext *loader_ctx, uint32 depth, uint8 opcode,
+                     char *error_buf, uint32 error_buf_size)
 {
 {
     BranchBlock *target_block, *cur_block;
     BranchBlock *target_block, *cur_block;
     BlockType *target_block_type;
     BlockType *target_block_type;
@@ -5441,7 +5443,7 @@ wasm_loader_check_br(WASMLoaderContext *loader_ctx, uint32 depth,
         /* Backup stack data since it may be changed in the below
         /* Backup stack data since it may be changed in the below
            push operations, and the stack data may be used when
            push operations, and the stack data may be used when
            checking other target blocks of opcode br_table */
            checking other target blocks of opcode br_table */
-        if (is_br_table) {
+        if (opcode == WASM_OP_BR_TABLE) {
             uint64 total_size;
             uint64 total_size;
 
 
             frame_ref_after_popped = loader_ctx->frame_ref;
             frame_ref_after_popped = loader_ctx->frame_ref;
@@ -5479,13 +5481,13 @@ wasm_loader_check_br(WASMLoaderContext *loader_ctx, uint32 depth,
         }
         }
 
 
 #if WASM_ENABLE_FAST_INTERP != 0
 #if WASM_ENABLE_FAST_INTERP != 0
-        emit_br_info(target_block);
+        emit_br_info(target_block, opcode == WASM_OP_BR);
 #endif
 #endif
 
 
         /* Restore the stack data, note that frame_ref_bottom,
         /* Restore the stack data, note that frame_ref_bottom,
            frame_reftype_map_bottom, frame_offset_bottom may be
            frame_reftype_map_bottom, frame_offset_bottom may be
            re-allocated in the above push operations */
            re-allocated in the above push operations */
-        if (is_br_table) {
+        if (opcode == WASM_OP_BR_TABLE) {
             uint32 total_size;
             uint32 total_size;
 
 
             /* The stack operand num should not be smaller than before
             /* The stack operand num should not be smaller than before
@@ -5529,7 +5531,7 @@ wasm_loader_check_br(WASMLoaderContext *loader_ctx, uint32 depth,
     }
     }
 
 
 #if WASM_ENABLE_FAST_INTERP != 0
 #if WASM_ENABLE_FAST_INTERP != 0
-    emit_br_info(target_block);
+    emit_br_info(target_block, opcode == WASM_OP_BR);
 #endif
 #endif
 
 
     ret = true;
     ret = true;
@@ -5548,14 +5550,14 @@ fail:
 
 
 static BranchBlock *
 static BranchBlock *
 check_branch_block(WASMLoaderContext *loader_ctx, uint8 **p_buf, uint8 *buf_end,
 check_branch_block(WASMLoaderContext *loader_ctx, uint8 **p_buf, uint8 *buf_end,
-                   bool is_br_table, char *error_buf, uint32 error_buf_size)
+                   uint8 opcode, char *error_buf, uint32 error_buf_size)
 {
 {
     uint8 *p = *p_buf, *p_end = buf_end;
     uint8 *p = *p_buf, *p_end = buf_end;
     BranchBlock *frame_csp_tmp;
     BranchBlock *frame_csp_tmp;
     uint32 depth;
     uint32 depth;
 
 
     read_leb_uint32(p, p_end, depth);
     read_leb_uint32(p, p_end, depth);
-    if (!wasm_loader_check_br(loader_ctx, depth, is_br_table, error_buf,
+    if (!wasm_loader_check_br(loader_ctx, depth, opcode, error_buf,
                               error_buf_size)) {
                               error_buf_size)) {
         goto fail;
         goto fail;
     }
     }
@@ -6179,7 +6181,7 @@ re_scan:
             case WASM_OP_BR:
             case WASM_OP_BR:
             {
             {
                 if (!(frame_csp_tmp =
                 if (!(frame_csp_tmp =
-                          check_branch_block(loader_ctx, &p, p_end, false,
+                          check_branch_block(loader_ctx, &p, p_end, opcode,
                                              error_buf, error_buf_size)))
                                              error_buf, error_buf_size)))
                     goto fail;
                     goto fail;
 
 
@@ -6193,7 +6195,7 @@ re_scan:
                 POP_I32();
                 POP_I32();
 
 
                 if (!(frame_csp_tmp =
                 if (!(frame_csp_tmp =
-                          check_branch_block(loader_ctx, &p, p_end, false,
+                          check_branch_block(loader_ctx, &p, p_end, opcode,
                                              error_buf, error_buf_size)))
                                              error_buf, error_buf_size)))
                     goto fail;
                     goto fail;
 
 
@@ -6223,7 +6225,7 @@ re_scan:
 #endif
 #endif
                 for (i = 0; i <= count; i++) {
                 for (i = 0; i <= count; i++) {
                     if (!(frame_csp_tmp =
                     if (!(frame_csp_tmp =
-                              check_branch_block(loader_ctx, &p, p_end, true,
+                              check_branch_block(loader_ctx, &p, p_end, opcode,
                                                  error_buf, error_buf_size)))
                                                  error_buf, error_buf_size)))
                         goto fail;
                         goto fail;