Просмотр исходного кода

Fix struct field offset and size in AOT loader (#2729)

And fix array.copy opcode translation.
Xu Jun 2 лет назад
Родитель
Сommit
f9ccffd6ba
2 измененных файлов с 43 добавлено и 26 удалено
  1. 20 3
      core/iwasm/aot/aot_loader.c
  2. 23 23
      core/iwasm/compilation/aot_emit_gc.c

+ 20 - 3
core/iwasm/aot/aot_loader.c

@@ -1377,6 +1377,7 @@ load_types(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
         else if (type_flag == WASM_TYPE_STRUCT) {
             AOTStructType *struct_type;
             uint16 field_count;
+            uint32 offset;
             read_uint16(buf, buf_end, field_count);
             read_uint16(buf, buf_end, ref_type_map_count);
             struct_type =
@@ -1387,6 +1388,7 @@ load_types(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
                 goto fail;
             }
 
+            offset = (uint32)sizeof(WASMStructObject);
             types[i] = (AOTType *)struct_type;
 
             struct_type->base_type.type_flag = type_flag;
@@ -1399,13 +1401,28 @@ load_types(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
 
             /* Read types of fields */
             for (j = 0; j < field_count; j++) {
+                uint8 field_type, field_size;
                 read_uint8(buf, buf_end, struct_type->fields[j].field_flags);
-                read_uint8(buf, buf_end, struct_type->fields[j].field_type);
+                read_uint8(buf, buf_end, field_type);
+                struct_type->fields[j].field_type = field_type;
+                struct_type->fields[j].field_size = field_size =
+                    (uint8)wasm_reftype_size(field_type);
+#if !(defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64) \
+      || defined(BUILD_TARGET_X86_32))
+                if (field_size == 2)
+                    offset = align_uint(offset, 2);
+                else if (field_size >= 4) /* field size is 4 or 8 */
+                    offset = align_uint(offset, 4);
+#endif
+                struct_type->fields[j].field_offset = offset;
+                offset += field_size;
                 LOG_VERBOSE("                field: %d, flags: %d, type: %d", j,
-                            struct_type->fields[i].field_flags,
-                            struct_type->fields[i].field_type);
+                            struct_type->fields[j].field_flags,
+                            struct_type->fields[j].field_type);
             }
 
+            struct_type->total_size = offset;
+
             /* If ref_type_map is not empty, read ref_type_map */
             if (ref_type_map_count > 0) {
 

+ 23 - 23
core/iwasm/compilation/aot_emit_gc.c

@@ -1381,22 +1381,18 @@ fail:
 
 #if WASM_ENABLE_GC_BINARYEN != 0
 static bool
-aot_call_wasm_obj_copy(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
-                       LLVMValueRef dst_obj, LLVMValueRef dst_offset,
-                       LLVMValueRef src_obj, LLVMValueRef src_offset,
-                       LLVMValueRef len)
+aot_call_wasm_array_obj_copy(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
+                             LLVMValueRef dst_obj, LLVMValueRef dst_offset,
+                             LLVMValueRef src_obj, LLVMValueRef src_offset,
+                             LLVMValueRef len)
 {
-    LLVMValueRef param_values[5], func, value, cmp;
+    LLVMValueRef param_values[5], func, value;
     LLVMTypeRef param_types[5], ret_type, func_type, func_ptr_type;
-    LLVMBasicBlockRef init_success;
-
-    ADD_BASIC_BLOCK(init_success, "init success");
-    MOVE_BLOCK_AFTER_CURR(init_success);
 
-    param_types[0] = INT8_PTR_TYPE;
+    param_types[0] = GC_REF_TYPE;
     param_types[1] = I32_TYPE;
-    param_types[2] = I32_TYPE;
-    param_types[3] = INT8_PTR_TYPE;
+    param_types[2] = GC_REF_TYPE;
+    param_types[3] = I32_TYPE;
     param_types[4] = I32_TYPE;
     ret_type = VOID_TYPE;
 
@@ -1409,7 +1405,7 @@ aot_call_wasm_obj_copy(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
     param_values[3] = src_offset;
     param_values[4] = len;
     if (!LLVMBuildCall2(comp_ctx->builder, func_type, func, param_values, 5,
-                        "call")) {
+                        "")) {
         aot_set_last_error("llvm build call failed.");
         goto fail;
     }
@@ -1446,20 +1442,21 @@ aot_compile_op_array_copy(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
         goto fail;
     }
 
-    if (!aot_emit_exception(comp_ctx, func_ctx, EXCE_NULL_GC_REF, true, cmp[0],
-                            check_objs_succ))
+    if (!aot_emit_exception(comp_ctx, func_ctx, EXCE_NULL_ARRAY_OBJ, true,
+                            cmp[0], check_objs_succ))
         goto fail;
 
     /* Create if block */
     ADD_BASIC_BLOCK(len_gt_zero, "len_gt_zero");
     MOVE_BLOCK_AFTER_CURR(len_gt_zero);
-    /* Create inner else block */
-    ADD_BASIC_BLOCK(inner_else, "inner_else");
-    MOVE_BLOCK_AFTER(inner_else, len_le_zero);
 
     /* Create else(end) block */
     ADD_BASIC_BLOCK(len_le_zero, "len_le_zero");
-    MOVE_BLOCK_AFTER_CURR(len_le_zero);
+    MOVE_BLOCK_AFTER(len_le_zero, len_gt_zero);
+
+    /* Create inner else block */
+    ADD_BASIC_BLOCK(inner_else, "inner_else");
+    MOVE_BLOCK_AFTER(inner_else, len_gt_zero);
 
     BUILD_ICMP(LLVMIntSGT, len, I32_ZERO, cmp[0], "cmp_len");
     BUILD_COND_BR(cmp[0], len_gt_zero, len_le_zero);
@@ -1474,7 +1471,7 @@ aot_compile_op_array_copy(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
     BUILD_ICMP(LLVMIntUGT, boundary, I32_CONST(UINT32_MAX), cmp[0],
                "boundary_check1");
     /* dst_offset + len > wasm_array_obj_length(dst_obj) */
-    if (!aot_get_array_obj_length(comp_ctx, func_ctx, dst_obj, &array_len))
+    if (!aot_array_obj_length(comp_ctx, dst_obj, &array_len))
         goto fail;
     BUILD_ICMP(LLVMIntUGT, boundary, array_len, cmp[1], "boundary_check2");
     /* src_offset > UINT32_MAX - len */
@@ -1485,7 +1482,7 @@ aot_compile_op_array_copy(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
     BUILD_ICMP(LLVMIntUGT, boundary, I32_CONST(UINT32_MAX), cmp[2],
                "boundary_check3");
     /* src_offset + len > wasm_array_obj_length(src_obj) */
-    if (!aot_get_array_obj_length(comp_ctx, func_ctx, src_obj, &array_len))
+    if (!aot_array_obj_length(comp_ctx, src_obj, &array_len))
         goto fail;
     BUILD_ICMP(LLVMIntUGT, boundary, array_len, cmp[3], "boundary_check4");
 
@@ -1501,10 +1498,13 @@ aot_compile_op_array_copy(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
                             cmp[0], inner_else))
         goto fail;
 
-    if (!aot_call_wasm_obj_copy(comp_ctx, func_ctx, dst_obj, dst_offset,
-                                src_obj, src_offset, len))
+    if (!aot_call_wasm_array_obj_copy(comp_ctx, func_ctx, dst_obj, dst_offset,
+                                      src_obj, src_offset, len))
         goto fail;
 
+    BUILD_BR(len_le_zero);
+    SET_BUILDER_POS(len_le_zero);
+
     return true;
 fail:
     return false;