From 801bd18696fe1fa3ee30495855f71454cc4533a3 Mon Sep 17 00:00:00 2001 From: Xu Jun Date: Tue, 1 Apr 2025 14:03:01 +0800 Subject: [PATCH] fix nested struct init value error in gc aot --- core/iwasm/aot/aot_loader.c | 240 ++++++++++++++++----- core/iwasm/aot/aot_runtime.c | 145 ++++++++++--- core/iwasm/compilation/aot_emit_aot_file.c | 224 ++++++++++++++----- 3 files changed, 466 insertions(+), 143 deletions(-) diff --git a/core/iwasm/aot/aot_loader.c b/core/iwasm/aot/aot_loader.c index 9ca64f9c82..2a5d196da2 100644 --- a/core/iwasm/aot/aot_loader.c +++ b/core/iwasm/aot/aot_loader.c @@ -1150,12 +1150,76 @@ load_memory_info(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module, #if WASM_ENABLE_GC != 0 static void -destroy_init_expr(InitializerExpression *expr) +destroy_init_expr_data_recursive(AOTModule *module, void *data) +{ + WASMStructNewInitValues *struct_init_values = + (WASMStructNewInitValues *)data; + WASMArrayNewInitValues *array_init_values = (WASMArrayNewInitValues *)data; + AOTType *wasm_type; + uint32 i; + + if (!data) + return; + + wasm_type = module->types[struct_init_values->type_idx]; + + /* The data can only be type of `WASMStructNewInitValues *` + or `WASMArrayNewInitValues *` */ + bh_assert(wasm_type->type_flag == WASM_TYPE_STRUCT + || wasm_type->type_flag == WASM_TYPE_ARRAY); + + if (wasm_type->type_flag == WASM_TYPE_STRUCT) { + AOTStructType *struct_type = (AOTStructType *)wasm_type; + WASMRefType *ref_type; + uint8 field_type; + + uint16 ref_type_map_index = 0; + for (i = 0; i < struct_init_values->count; i++) { + field_type = struct_type->fields[i].field_type; + if (wasm_is_type_multi_byte_type(field_type)) + ref_type = + struct_type->ref_type_maps[ref_type_map_index++].ref_type; + else + ref_type = NULL; + if (wasm_reftype_is_subtype_of(field_type, ref_type, + REF_TYPE_STRUCTREF, NULL, + module->types, module->type_count) + || wasm_reftype_is_subtype_of( + field_type, ref_type, REF_TYPE_ARRAYREF, NULL, + module->types, module->type_count)) { + destroy_init_expr_data_recursive( + module, struct_init_values->fields[i].data); + } + } + } + else if (wasm_type->type_flag == WASM_TYPE_ARRAY) { + AOTArrayType *array_type = (AOTArrayType *)wasm_type; + WASMRefType *elem_ref_type = array_type->elem_ref_type; + uint8 elem_type = array_type->elem_type; + + for (i = 0; i < array_init_values->length; i++) { + if (wasm_reftype_is_subtype_of(elem_type, elem_ref_type, + REF_TYPE_STRUCTREF, NULL, + module->types, module->type_count) + || wasm_reftype_is_subtype_of( + elem_type, elem_ref_type, REF_TYPE_ARRAYREF, NULL, + module->types, module->type_count)) { + destroy_init_expr_data_recursive( + module, array_init_values->elem_data[i].data); + } + } + } + + wasm_runtime_free(data); +} + +static void +destroy_init_expr(AOTModule *module, InitializerExpression *expr) { if (expr->init_expr_type == INIT_EXPR_TYPE_STRUCT_NEW || expr->init_expr_type == INIT_EXPR_TYPE_ARRAY_NEW || expr->init_expr_type == INIT_EXPR_TYPE_ARRAY_NEW_FIXED) { - wasm_runtime_free(expr->u.data); + destroy_init_expr_data_recursive(module, expr->u.data); } } #endif /* end of WASM_ENABLE_GC != 0 */ @@ -1173,7 +1237,8 @@ destroy_tables(AOTTable *tables) } static void -destroy_table_init_data_list(AOTTableInitData **data_list, uint32 count) +destroy_table_init_data_list(AOTModule *module, AOTTableInitData **data_list, + uint32 count) { uint32 i; for (i = 0; i < count; i++) @@ -1181,7 +1246,7 @@ destroy_table_init_data_list(AOTTableInitData **data_list, uint32 count) #if WASM_ENABLE_GC != 0 uint32 j; for (j = 0; j < data_list[i]->value_count; j++) { - destroy_init_expr(&data_list[i]->init_values[j]); + destroy_init_expr(module, &data_list[i]->init_values[j]); } #endif wasm_runtime_free(data_list[i]); @@ -1189,6 +1254,109 @@ destroy_table_init_data_list(AOTTableInitData **data_list, uint32 count) wasm_runtime_free(data_list); } +static bool +load_struct_init_expr_recursive(const uint8 **p_buf, const uint8 *buf_end, + AOTModule *module, uint32 type_idx, + WASMValue *init_value, char *error_buf, + uint32 error_buf_size) +{ + const uint8 *buf = *p_buf; + WASMStructNewInitValues *init_values = NULL; + AOTStructType *struct_type = NULL; + WASMRefTypeMap *ref_type_map = NULL; + uint32 field_count; + uint64 size; + + if (type_idx >= module->type_count) { + set_error_buf(error_buf, error_buf_size, "unknown struct type."); + goto fail; + } + + read_uint32(buf, buf_end, field_count); + + struct_type = (AOTStructType *)module->types[type_idx]; + ref_type_map = struct_type->ref_type_maps; + + if (field_count > 0) { + uint32 i; + + if (struct_type->field_count != field_count) { + set_error_buf(error_buf, error_buf_size, "invalid field count."); + goto fail; + } + + size = offsetof(WASMStructNewInitValues, fields) + + sizeof(WASMValue) * (uint64)field_count; + if (!(init_values = loader_malloc(size, error_buf, error_buf_size))) { + return false; + } + + init_values->count = field_count; + init_values->type_idx = type_idx; + + for (i = 0; i < field_count; i++) { + uint8 field_type = struct_type->fields[i].field_type; + WASMRefType *field_ref_type = NULL; + if (wasm_is_type_multi_byte_type(field_type)) { + field_ref_type = ref_type_map->ref_type; + } + + if (wasm_reftype_is_subtype_of(field_type, field_ref_type, + REF_TYPE_STRUCTREF, NULL, + module->types, module->type_count)) { + bh_assert(field_ref_type); + if (!load_struct_init_expr_recursive( + &buf, buf_end, module, + field_ref_type->ref_ht_typeidx.type_idx, + &init_values->fields[i], error_buf, error_buf_size)) { + goto fail; + } + } + else if (wasm_reftype_is_subtype_of( + field_type, field_ref_type, REF_TYPE_ARRAYREF, NULL, + module->types, module->type_count)) { + bh_assert(0); + } + else if (wasm_reftype_is_subtype_of( + field_type, field_ref_type, REF_TYPE_FUNCREF, NULL, + module->types, module->type_count)) { + read_uint32(buf, buf_end, init_values->fields[i].ref_index); + } + else { + uint32 field_size = + wasm_value_type_size(struct_type->fields[i].field_type); + if (field_size <= sizeof(uint32)) + read_uint32(buf, buf_end, init_values->fields[i].u32); + else if (field_size == sizeof(uint64)) + read_uint64(buf, buf_end, init_values->fields[i].u64); + else if (field_size == sizeof(uint64) * 2) + read_byte_array(buf, buf_end, &init_values->fields[i], + field_size); + else { + bh_assert(0); + } + } + + if (wasm_is_type_multi_byte_type(field_type)) { + ref_type_map++; + } + } + + init_value->data = init_values; + } + else { + /* struct.new_default */ + init_value->data = NULL; + } + + *p_buf = buf; + return true; + +fail: + destroy_init_expr_data_recursive(module, init_values); + return false; +} + static bool load_init_expr(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module, InitializerExpression *expr, char *error_buf, @@ -1239,58 +1407,16 @@ load_init_expr(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module, break; case INIT_EXPR_TYPE_STRUCT_NEW: { - uint64 size; - uint32 type_idx, field_count; - AOTStructType *struct_type = NULL; - WASMStructNewInitValues *init_values = NULL; + uint32 type_idx; read_uint32(buf, buf_end, type_idx); - read_uint32(buf, buf_end, field_count); - size = offsetof(WASMStructNewInitValues, fields) - + sizeof(WASMValue) * (uint64)field_count; - if (!(init_values = - loader_malloc(size, error_buf, error_buf_size))) { - return false; - } - free_if_fail = true; - init_values->count = field_count; - init_values->type_idx = type_idx; - expr->u.data = init_values; - - if (type_idx >= module->type_count) { - set_error_buf(error_buf, error_buf_size, - "unknown struct type."); + if (!load_struct_init_expr_recursive(&buf, buf_end, module, + type_idx, &expr->u, error_buf, + error_buf_size)) { goto fail; } - struct_type = (AOTStructType *)module->types[type_idx]; - - if (struct_type->field_count != field_count) { - set_error_buf(error_buf, error_buf_size, - "invalid field count."); - goto fail; - } - - if (field_count > 0) { - uint32 i; - - for (i = 0; i < field_count; i++) { - uint32 field_size = - wasm_value_type_size(struct_type->fields[i].field_type); - if (field_size <= sizeof(uint32)) - read_uint32(buf, buf_end, init_values->fields[i].u32); - else if (field_size == sizeof(uint64)) - read_uint64(buf, buf_end, init_values->fields[i].u64); - else if (field_size == sizeof(uint64) * 2) - read_byte_array(buf, buf_end, &init_values->fields[i], - field_size); - else { - bh_assert(0); - } - } - } - break; } case INIT_EXPR_TYPE_STRUCT_NEW_DEFAULT: @@ -1362,7 +1488,7 @@ load_init_expr(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module, fail: #if WASM_ENABLE_GC != 0 if (free_if_fail) { - wasm_runtime_free(expr->u.data); + destroy_init_expr_data_recursive(module, expr->u.data); } #else (void)free_if_fail; @@ -4442,19 +4568,16 @@ aot_unload(AOTModule *module) #if WASM_ENABLE_GC != 0 uint32 i; for (i = 0; i < module->table_count; i++) { - destroy_init_expr(&module->tables[i].init_expr); + destroy_init_expr(module, &module->tables[i].init_expr); } #endif destroy_tables(module->tables); } if (module->table_init_data_list) - destroy_table_init_data_list(module->table_init_data_list, + destroy_table_init_data_list(module, module->table_init_data_list, module->table_init_data_count); - if (module->types) - destroy_types(module->types, module->type_count); - if (module->import_globals) destroy_import_globals(module->import_globals); @@ -4462,12 +4585,15 @@ aot_unload(AOTModule *module) #if WASM_ENABLE_GC != 0 uint32 i; for (i = 0; i < module->global_count; i++) { - destroy_init_expr(&module->globals[i].init_expr); + destroy_init_expr(module, &module->globals[i].init_expr); } #endif destroy_globals(module->globals); } + if (module->types) + destroy_types(module->types, module->type_count); + if (module->import_funcs) destroy_import_funcs(module->import_funcs); diff --git a/core/iwasm/aot/aot_runtime.c b/core/iwasm/aot/aot_runtime.c index bf7f51964f..6595ce3ec0 100644 --- a/core/iwasm/aot/aot_runtime.c +++ b/core/iwasm/aot/aot_runtime.c @@ -442,6 +442,116 @@ assign_table_init_value(AOTModuleInstance *module_inst, AOTModule *module, return true; } + +static WASMStructObjectRef +instantiate_struct_global_recursive(AOTModuleInstance *module_inst, + AOTModule *module, uint32 type_idx, + uint8 flag, + WASMStructNewInitValues *init_values, + char *error_buf, uint32 error_buf_size) +{ + WASMRttType *rtt_type; + WASMStructObjectRef struct_obj; + WASMStructType *struct_type; + + struct_type = (WASMStructType *)module->types[type_idx]; + + if (!(rtt_type = wasm_rtt_type_new((WASMType *)struct_type, type_idx, + module->rtt_types, module->type_count, + &module->rtt_type_lock))) { + set_error_buf(error_buf, error_buf_size, "create rtt object failed"); + return NULL; + } + + if (!(struct_obj = wasm_struct_obj_new_internal( + ((AOTModuleInstanceExtra *)module_inst->e)->common.gc_heap_handle, + rtt_type))) { + set_error_buf(error_buf, error_buf_size, "create struct object failed"); + return NULL; + } + + if (flag == INIT_EXPR_TYPE_STRUCT_NEW) { + uint32 field_idx; + WASMRefTypeMap *ref_type_map = struct_type->ref_type_maps; + + bh_assert(init_values->count == struct_type->field_count); + + for (field_idx = 0; field_idx < init_values->count; field_idx++) { + uint8 field_type = struct_type->fields[field_idx].field_type; + WASMRefType *field_ref_type = NULL; + if (wasm_is_type_multi_byte_type(field_type)) { + field_ref_type = ref_type_map->ref_type; + } + + if (wasm_reftype_is_subtype_of(field_type, field_ref_type, + REF_TYPE_STRUCTREF, NULL, + module->types, module->type_count) + || wasm_reftype_is_subtype_of(field_type, field_ref_type, + REF_TYPE_ARRAYREF, NULL, + module->types, module->type_count) + || wasm_reftype_is_subtype_of( + field_type, field_ref_type, REF_TYPE_FUNCREF, NULL, + module->types, module->type_count)) { + WASMType *wasm_type; + int32 heap_type = + ref_type_map->ref_type->ref_ht_common.heap_type; + WASMValue *wasm_value = &init_values->fields[field_idx]; + WASMValue field_value = { 0 }; + + bh_assert(heap_type >= 0); + wasm_type = module->types[heap_type]; + + bh_assert(wasm_type->type_flag == WASM_TYPE_STRUCT + || wasm_type->type_flag == WASM_TYPE_ARRAY + || wasm_type->type_flag == WASM_TYPE_FUNC); + + if (wasm_type->type_flag == WASM_TYPE_STRUCT) { + WASMStructNewInitValues *init_values1 = + (WASMStructNewInitValues *)wasm_value->data; + WASMStructObjectRef field = + instantiate_struct_global_recursive( + module_inst, module, heap_type, + init_values1 ? INIT_EXPR_TYPE_STRUCT_NEW + : INIT_EXPR_TYPE_STRUCT_NEW_DEFAULT, + init_values1, error_buf, error_buf_size); + field_value.gc_obj = (WASMObjectRef)field; + wasm_struct_obj_set_field(struct_obj, field_idx, + &field_value); + } + else if (wasm_type->type_flag == WASM_TYPE_ARRAY) { + /* struct object's field is an array obj */ + set_error_buf(error_buf, error_buf_size, + "array as a field in struct object is " + "not supported in constant init expr"); + return NULL; + } + else if (wasm_type->type_flag == WASM_TYPE_FUNC) { + WASMFuncObjectRef func_obj = NULL; + /* UINT32_MAX indicates that it is a null reference */ + if (wasm_value->u32 != UINT32_MAX) { + if (!(func_obj = aot_create_func_obj( + module_inst, wasm_value->u32, false, + error_buf, error_buf_size))) { + return NULL; + } + } + field_value.gc_obj = (WASMObjectRef)func_obj; + wasm_struct_obj_set_field(struct_obj, field_idx, + &field_value); + } + } + else { + wasm_struct_obj_set_field(struct_obj, field_idx, + &init_values->fields[field_idx]); + } + if (wasm_is_type_multi_byte_type(field_type)) { + ref_type_map++; + } + } + } + + return struct_obj; +} #endif /* end of WASM_ENABLE_GC != 0 */ static bool @@ -538,9 +648,7 @@ global_instantiate(AOTModuleInstance *module_inst, AOTModule *module, case INIT_EXPR_TYPE_STRUCT_NEW: case INIT_EXPR_TYPE_STRUCT_NEW_DEFAULT: { - WASMRttType *rtt_type; WASMStructObjectRef struct_obj; - WASMStructType *struct_type; WASMStructNewInitValues *init_values = NULL; uint32 type_idx; @@ -552,38 +660,13 @@ global_instantiate(AOTModuleInstance *module_inst, AOTModule *module, type_idx = init_expr->u.type_index; } - struct_type = (WASMStructType *)module->types[type_idx]; - - if (!(rtt_type = wasm_rtt_type_new( - (WASMType *)struct_type, type_idx, module->rtt_types, - module->type_count, &module->rtt_type_lock))) { - set_error_buf(error_buf, error_buf_size, - "create rtt object failed"); - return false; - } - - if (!(struct_obj = wasm_struct_obj_new_internal( - ((AOTModuleInstanceExtra *)module_inst->e) - ->common.gc_heap_handle, - rtt_type))) { - set_error_buf(error_buf, error_buf_size, - "create struct object failed"); + struct_obj = instantiate_struct_global_recursive( + module_inst, module, type_idx, flag, init_values, error_buf, + error_buf_size); + if (!struct_obj) { return false; } - if (flag == INIT_EXPR_TYPE_STRUCT_NEW) { - uint32 field_idx; - - bh_assert(init_values->count == struct_type->field_count); - - for (field_idx = 0; field_idx < init_values->count; - field_idx++) { - wasm_struct_obj_set_field( - struct_obj, field_idx, - &init_values->fields[field_idx]); - } - } - PUT_REF_TO_ADDR(p, struct_obj); break; } diff --git a/core/iwasm/compilation/aot_emit_aot_file.c b/core/iwasm/compilation/aot_emit_aot_file.c index ecb75968fc..8a3ddfe096 100644 --- a/core/iwasm/compilation/aot_emit_aot_file.c +++ b/core/iwasm/compilation/aot_emit_aot_file.c @@ -207,6 +207,85 @@ get_mem_info_size(AOTCompContext *comp_ctx, AOTCompData *comp_data) comp_data->mem_init_data_count); } +#if WASM_ENABLE_GC != 0 +static uint32 +get_struct_init_expr_size_recursive(const AOTCompContext *comp_ctx, + const AOTCompData *comp_data, + WASMStructNewInitValues *init_values, + uint8 flag) +{ + uint32 i; + uint32 size = 0; + WASMModule *module = comp_data->wasm_module; + uint32 type_idx = init_values->type_idx; + WASMStructType *struct_type = + (WASMStructType *)module->types[init_values->type_idx]; + WASMRefTypeMap *ref_type_map = NULL; + + bh_assert(type_idx < module->type_count); + bh_assert(struct_type); + bh_assert(struct_type->field_count == init_values->count); + + ref_type_map = struct_type->ref_type_maps; + + /* field_count + fields */ + size += sizeof(uint32); + + for (i = 0; i < init_values->count; i++) { + uint8 field_type = struct_type->fields[i].field_type; + WASMRefType *field_ref_type = NULL; + if (wasm_is_type_multi_byte_type(field_type)) { + field_ref_type = ref_type_map->ref_type; + } + + if (wasm_reftype_is_subtype_of(field_type, field_ref_type, + REF_TYPE_STRUCTREF, NULL, module->types, + module->type_count)) { + if (init_values->fields[i].data) { + /* struct.new */ + WASMStructNewInitValues *init_values1 = + (WASMStructNewInitValues *)init_values->fields[i].data; + size += get_struct_init_expr_size_recursive( + comp_ctx, comp_data, init_values1, + init_values1 ? INIT_EXPR_TYPE_STRUCT_NEW + : INIT_EXPR_TYPE_STRUCT_NEW_DEFAULT); + } + else { + /* 0 */ + size += sizeof(uint32); + } + } + else if (wasm_reftype_is_subtype_of( + field_type, field_ref_type, REF_TYPE_ARRAYREF, NULL, + module->types, module->type_count)) { + /* Not supported */ + bh_assert(0); + } + else if (wasm_reftype_is_subtype_of( + field_type, field_ref_type, REF_TYPE_FUNCREF, NULL, + module->types, module->type_count)) { + /* ref_index */ + size += sizeof(uint32); + } + else { + uint32 field_size; + + field_size = wasm_value_type_size_internal( + struct_type->fields[i].field_type, comp_ctx->pointer_size); + if (field_size < sizeof(uint32)) + field_size = sizeof(uint32); + size += field_size; + } + + if (wasm_is_type_multi_byte_type(field_type)) { + ref_type_map++; + } + } + + return size; +} +#endif /* end of WASM_ENABLE_GC != 0 */ + static uint32 get_init_expr_size(const AOTCompContext *comp_ctx, const AOTCompData *comp_data, InitializerExpression *expr) @@ -246,35 +325,15 @@ get_init_expr_size(const AOTCompContext *comp_ctx, const AOTCompData *comp_data, break; case INIT_EXPR_TYPE_STRUCT_NEW: { - uint32 i; - WASMStructNewInitValues *struct_new_init_values = - (WASMStructNewInitValues *)expr->u.data; - - /* type_index + field_count + fields */ - size += sizeof(uint32) + sizeof(uint32); - - bh_assert(struct_new_init_values->type_idx < module->type_count); - - for (i = 0; i < struct_new_init_values->count; i++) { - WASMStructType *struct_type = - (WASMStructType *) - module->types[struct_new_init_values->type_idx]; - uint32 field_size; - - bh_assert(struct_type); - bh_assert(struct_type->field_count - == struct_new_init_values->count); - - field_size = wasm_value_type_size_internal( - struct_type->fields[i].field_type, comp_ctx->pointer_size); - if (field_size < sizeof(uint32)) - field_size = sizeof(uint32); - size += field_size; - } + /* type_index */ + size += sizeof(uint32); + size += get_struct_init_expr_size_recursive( + comp_ctx, comp_data, (WASMStructNewInitValues *)expr->u.data, + INIT_EXPR_TYPE_STRUCT_NEW); break; } case INIT_EXPR_TYPE_STRUCT_NEW_DEFAULT: - /* type_index */ + /* 0 */ size += sizeof(uint32); break; case INIT_EXPR_TYPE_ARRAY_NEW_DEFAULT: @@ -1805,6 +1864,85 @@ aot_emit_mem_info(uint8 *buf, uint8 *buf_end, uint32 *p_offset, return true; } +#if WASM_ENABLE_GC != 0 +static bool +aot_emit_struct_init_recursive(uint8 *buf, uint8 *buf_end, uint32 *p_offset, + AOTCompContext *comp_ctx, + WASMStructNewInitValues *init_values) +{ + uint32 offset = *p_offset; + uint32 i; + WASMModule *module = comp_ctx->comp_data->wasm_module; + WASMStructType *struct_type = NULL; + WASMRefTypeMap *ref_type_map = NULL; + + EMIT_U32(init_values->count); + + bh_assert(init_values->type_idx < module->type_count); + + struct_type = (WASMStructType *)module->types[init_values->type_idx]; + ref_type_map = struct_type->ref_type_maps; + + bh_assert(struct_type); + bh_assert(struct_type->field_count == init_values->count); + + for (i = 0; i < init_values->count; i++) { + uint8 field_type = struct_type->fields[i].field_type; + WASMRefType *field_ref_type = NULL; + if (wasm_is_type_multi_byte_type(field_type)) { + field_ref_type = ref_type_map->ref_type; + } + + if (wasm_reftype_is_subtype_of(field_type, field_ref_type, + REF_TYPE_STRUCTREF, NULL, module->types, + module->type_count)) { + if (init_values->fields[i].data) { + /* struct.new */ + if (!aot_emit_struct_init_recursive( + buf, buf_end, &offset, comp_ctx, + (WASMStructNewInitValues *)init_values->fields[i].data)) + return false; + } + else { + /* struct.new_default */ + EMIT_U32(0); + } + } + else if (wasm_reftype_is_subtype_of( + field_type, field_ref_type, REF_TYPE_ARRAYREF, NULL, + module->types, module->type_count)) { + bh_assert(0); + } + else if (wasm_reftype_is_subtype_of( + field_type, field_ref_type, REF_TYPE_FUNCREF, NULL, + module->types, module->type_count)) { + EMIT_U32(init_values->fields[i].ref_index); + } + else { + /* Value types */ + uint32 field_size = wasm_value_type_size_internal( + struct_type->fields[i].field_type, comp_ctx->pointer_size); + if (field_size <= sizeof(uint32)) + EMIT_U32(init_values->fields[i].u32); + else if (field_size == sizeof(uint64)) + EMIT_U64(init_values->fields[i].u64); + else if (field_size == sizeof(uint64) * 2) + EMIT_V128(init_values->fields[i].v128); + else { + bh_assert(0); + } + } + + if (wasm_is_type_multi_byte_type(field_type)) { + ref_type_map++; + } + } + + *p_offset = offset; + return true; +} +#endif /* end of WASM_ENABLE_GC != 0 */ + static bool aot_emit_init_expr(uint8 *buf, uint8 *buf_end, uint32 *p_offset, AOTCompContext *comp_ctx, InitializerExpression *expr) @@ -1844,36 +1982,12 @@ aot_emit_init_expr(uint8 *buf, uint8 *buf_end, uint32 *p_offset, break; case INIT_EXPR_TYPE_STRUCT_NEW: { - uint32 i; - WASMStructNewInitValues *init_values = - (WASMStructNewInitValues *)expr->u.data; - WASMStructType *struct_type = NULL; - - EMIT_U32(init_values->type_idx); - EMIT_U32(init_values->count); - - bh_assert(init_values->type_idx < module->type_count); - - struct_type = - (WASMStructType *)module->types[init_values->type_idx]; - - bh_assert(struct_type); - bh_assert(struct_type->field_count == init_values->count); - - for (i = 0; i < init_values->count; i++) { - uint32 field_size = wasm_value_type_size_internal( - struct_type->fields[i].field_type, comp_ctx->pointer_size); - if (field_size <= sizeof(uint32)) - EMIT_U32(init_values->fields[i].u32); - else if (field_size == sizeof(uint64)) - EMIT_U64(init_values->fields[i].u64); - else if (field_size == sizeof(uint64) * 2) - EMIT_V128(init_values->fields[i].v128); - else { - bh_assert(0); - } + EMIT_U32(((WASMStructNewInitValues *)expr->u.data)->type_idx); + if (!aot_emit_struct_init_recursive( + buf, buf_end, &offset, comp_ctx, + (WASMStructNewInitValues *)expr->u.data)) { + return false; } - break; } case INIT_EXPR_TYPE_STRUCT_NEW_DEFAULT: