Skip to content

Commit 801bd18

Browse files
committed
fix nested struct init value error in gc aot
1 parent b8dde72 commit 801bd18

3 files changed

Lines changed: 466 additions & 143 deletions

File tree

core/iwasm/aot/aot_loader.c

Lines changed: 183 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1150,12 +1150,76 @@ load_memory_info(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
11501150

11511151
#if WASM_ENABLE_GC != 0
11521152
static void
1153-
destroy_init_expr(InitializerExpression *expr)
1153+
destroy_init_expr_data_recursive(AOTModule *module, void *data)
1154+
{
1155+
WASMStructNewInitValues *struct_init_values =
1156+
(WASMStructNewInitValues *)data;
1157+
WASMArrayNewInitValues *array_init_values = (WASMArrayNewInitValues *)data;
1158+
AOTType *wasm_type;
1159+
uint32 i;
1160+
1161+
if (!data)
1162+
return;
1163+
1164+
wasm_type = module->types[struct_init_values->type_idx];
1165+
1166+
/* The data can only be type of `WASMStructNewInitValues *`
1167+
or `WASMArrayNewInitValues *` */
1168+
bh_assert(wasm_type->type_flag == WASM_TYPE_STRUCT
1169+
|| wasm_type->type_flag == WASM_TYPE_ARRAY);
1170+
1171+
if (wasm_type->type_flag == WASM_TYPE_STRUCT) {
1172+
AOTStructType *struct_type = (AOTStructType *)wasm_type;
1173+
WASMRefType *ref_type;
1174+
uint8 field_type;
1175+
1176+
uint16 ref_type_map_index = 0;
1177+
for (i = 0; i < struct_init_values->count; i++) {
1178+
field_type = struct_type->fields[i].field_type;
1179+
if (wasm_is_type_multi_byte_type(field_type))
1180+
ref_type =
1181+
struct_type->ref_type_maps[ref_type_map_index++].ref_type;
1182+
else
1183+
ref_type = NULL;
1184+
if (wasm_reftype_is_subtype_of(field_type, ref_type,
1185+
REF_TYPE_STRUCTREF, NULL,
1186+
module->types, module->type_count)
1187+
|| wasm_reftype_is_subtype_of(
1188+
field_type, ref_type, REF_TYPE_ARRAYREF, NULL,
1189+
module->types, module->type_count)) {
1190+
destroy_init_expr_data_recursive(
1191+
module, struct_init_values->fields[i].data);
1192+
}
1193+
}
1194+
}
1195+
else if (wasm_type->type_flag == WASM_TYPE_ARRAY) {
1196+
AOTArrayType *array_type = (AOTArrayType *)wasm_type;
1197+
WASMRefType *elem_ref_type = array_type->elem_ref_type;
1198+
uint8 elem_type = array_type->elem_type;
1199+
1200+
for (i = 0; i < array_init_values->length; i++) {
1201+
if (wasm_reftype_is_subtype_of(elem_type, elem_ref_type,
1202+
REF_TYPE_STRUCTREF, NULL,
1203+
module->types, module->type_count)
1204+
|| wasm_reftype_is_subtype_of(
1205+
elem_type, elem_ref_type, REF_TYPE_ARRAYREF, NULL,
1206+
module->types, module->type_count)) {
1207+
destroy_init_expr_data_recursive(
1208+
module, array_init_values->elem_data[i].data);
1209+
}
1210+
}
1211+
}
1212+
1213+
wasm_runtime_free(data);
1214+
}
1215+
1216+
static void
1217+
destroy_init_expr(AOTModule *module, InitializerExpression *expr)
11541218
{
11551219
if (expr->init_expr_type == INIT_EXPR_TYPE_STRUCT_NEW
11561220
|| expr->init_expr_type == INIT_EXPR_TYPE_ARRAY_NEW
11571221
|| expr->init_expr_type == INIT_EXPR_TYPE_ARRAY_NEW_FIXED) {
1158-
wasm_runtime_free(expr->u.data);
1222+
destroy_init_expr_data_recursive(module, expr->u.data);
11591223
}
11601224
}
11611225
#endif /* end of WASM_ENABLE_GC != 0 */
@@ -1173,22 +1237,126 @@ destroy_tables(AOTTable *tables)
11731237
}
11741238

11751239
static void
1176-
destroy_table_init_data_list(AOTTableInitData **data_list, uint32 count)
1240+
destroy_table_init_data_list(AOTModule *module, AOTTableInitData **data_list,
1241+
uint32 count)
11771242
{
11781243
uint32 i;
11791244
for (i = 0; i < count; i++)
11801245
if (data_list[i]) {
11811246
#if WASM_ENABLE_GC != 0
11821247
uint32 j;
11831248
for (j = 0; j < data_list[i]->value_count; j++) {
1184-
destroy_init_expr(&data_list[i]->init_values[j]);
1249+
destroy_init_expr(module, &data_list[i]->init_values[j]);
11851250
}
11861251
#endif
11871252
wasm_runtime_free(data_list[i]);
11881253
}
11891254
wasm_runtime_free(data_list);
11901255
}
11911256

1257+
static bool
1258+
load_struct_init_expr_recursive(const uint8 **p_buf, const uint8 *buf_end,
1259+
AOTModule *module, uint32 type_idx,
1260+
WASMValue *init_value, char *error_buf,
1261+
uint32 error_buf_size)
1262+
{
1263+
const uint8 *buf = *p_buf;
1264+
WASMStructNewInitValues *init_values = NULL;
1265+
AOTStructType *struct_type = NULL;
1266+
WASMRefTypeMap *ref_type_map = NULL;
1267+
uint32 field_count;
1268+
uint64 size;
1269+
1270+
if (type_idx >= module->type_count) {
1271+
set_error_buf(error_buf, error_buf_size, "unknown struct type.");
1272+
goto fail;
1273+
}
1274+
1275+
read_uint32(buf, buf_end, field_count);
1276+
1277+
struct_type = (AOTStructType *)module->types[type_idx];
1278+
ref_type_map = struct_type->ref_type_maps;
1279+
1280+
if (field_count > 0) {
1281+
uint32 i;
1282+
1283+
if (struct_type->field_count != field_count) {
1284+
set_error_buf(error_buf, error_buf_size, "invalid field count.");
1285+
goto fail;
1286+
}
1287+
1288+
size = offsetof(WASMStructNewInitValues, fields)
1289+
+ sizeof(WASMValue) * (uint64)field_count;
1290+
if (!(init_values = loader_malloc(size, error_buf, error_buf_size))) {
1291+
return false;
1292+
}
1293+
1294+
init_values->count = field_count;
1295+
init_values->type_idx = type_idx;
1296+
1297+
for (i = 0; i < field_count; i++) {
1298+
uint8 field_type = struct_type->fields[i].field_type;
1299+
WASMRefType *field_ref_type = NULL;
1300+
if (wasm_is_type_multi_byte_type(field_type)) {
1301+
field_ref_type = ref_type_map->ref_type;
1302+
}
1303+
1304+
if (wasm_reftype_is_subtype_of(field_type, field_ref_type,
1305+
REF_TYPE_STRUCTREF, NULL,
1306+
module->types, module->type_count)) {
1307+
bh_assert(field_ref_type);
1308+
if (!load_struct_init_expr_recursive(
1309+
&buf, buf_end, module,
1310+
field_ref_type->ref_ht_typeidx.type_idx,
1311+
&init_values->fields[i], error_buf, error_buf_size)) {
1312+
goto fail;
1313+
}
1314+
}
1315+
else if (wasm_reftype_is_subtype_of(
1316+
field_type, field_ref_type, REF_TYPE_ARRAYREF, NULL,
1317+
module->types, module->type_count)) {
1318+
bh_assert(0);
1319+
}
1320+
else if (wasm_reftype_is_subtype_of(
1321+
field_type, field_ref_type, REF_TYPE_FUNCREF, NULL,
1322+
module->types, module->type_count)) {
1323+
read_uint32(buf, buf_end, init_values->fields[i].ref_index);
1324+
}
1325+
else {
1326+
uint32 field_size =
1327+
wasm_value_type_size(struct_type->fields[i].field_type);
1328+
if (field_size <= sizeof(uint32))
1329+
read_uint32(buf, buf_end, init_values->fields[i].u32);
1330+
else if (field_size == sizeof(uint64))
1331+
read_uint64(buf, buf_end, init_values->fields[i].u64);
1332+
else if (field_size == sizeof(uint64) * 2)
1333+
read_byte_array(buf, buf_end, &init_values->fields[i],
1334+
field_size);
1335+
else {
1336+
bh_assert(0);
1337+
}
1338+
}
1339+
1340+
if (wasm_is_type_multi_byte_type(field_type)) {
1341+
ref_type_map++;
1342+
}
1343+
}
1344+
1345+
init_value->data = init_values;
1346+
}
1347+
else {
1348+
/* struct.new_default */
1349+
init_value->data = NULL;
1350+
}
1351+
1352+
*p_buf = buf;
1353+
return true;
1354+
1355+
fail:
1356+
destroy_init_expr_data_recursive(module, init_values);
1357+
return false;
1358+
}
1359+
11921360
static bool
11931361
load_init_expr(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
11941362
InitializerExpression *expr, char *error_buf,
@@ -1239,58 +1407,16 @@ load_init_expr(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
12391407
break;
12401408
case INIT_EXPR_TYPE_STRUCT_NEW:
12411409
{
1242-
uint64 size;
1243-
uint32 type_idx, field_count;
1244-
AOTStructType *struct_type = NULL;
1245-
WASMStructNewInitValues *init_values = NULL;
1410+
uint32 type_idx;
12461411

12471412
read_uint32(buf, buf_end, type_idx);
1248-
read_uint32(buf, buf_end, field_count);
12491413

1250-
size = offsetof(WASMStructNewInitValues, fields)
1251-
+ sizeof(WASMValue) * (uint64)field_count;
1252-
if (!(init_values =
1253-
loader_malloc(size, error_buf, error_buf_size))) {
1254-
return false;
1255-
}
1256-
free_if_fail = true;
1257-
init_values->count = field_count;
1258-
init_values->type_idx = type_idx;
1259-
expr->u.data = init_values;
1260-
1261-
if (type_idx >= module->type_count) {
1262-
set_error_buf(error_buf, error_buf_size,
1263-
"unknown struct type.");
1414+
if (!load_struct_init_expr_recursive(&buf, buf_end, module,
1415+
type_idx, &expr->u, error_buf,
1416+
error_buf_size)) {
12641417
goto fail;
12651418
}
12661419

1267-
struct_type = (AOTStructType *)module->types[type_idx];
1268-
1269-
if (struct_type->field_count != field_count) {
1270-
set_error_buf(error_buf, error_buf_size,
1271-
"invalid field count.");
1272-
goto fail;
1273-
}
1274-
1275-
if (field_count > 0) {
1276-
uint32 i;
1277-
1278-
for (i = 0; i < field_count; i++) {
1279-
uint32 field_size =
1280-
wasm_value_type_size(struct_type->fields[i].field_type);
1281-
if (field_size <= sizeof(uint32))
1282-
read_uint32(buf, buf_end, init_values->fields[i].u32);
1283-
else if (field_size == sizeof(uint64))
1284-
read_uint64(buf, buf_end, init_values->fields[i].u64);
1285-
else if (field_size == sizeof(uint64) * 2)
1286-
read_byte_array(buf, buf_end, &init_values->fields[i],
1287-
field_size);
1288-
else {
1289-
bh_assert(0);
1290-
}
1291-
}
1292-
}
1293-
12941420
break;
12951421
}
12961422
case INIT_EXPR_TYPE_STRUCT_NEW_DEFAULT:
@@ -1362,7 +1488,7 @@ load_init_expr(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
13621488
fail:
13631489
#if WASM_ENABLE_GC != 0
13641490
if (free_if_fail) {
1365-
wasm_runtime_free(expr->u.data);
1491+
destroy_init_expr_data_recursive(module, expr->u.data);
13661492
}
13671493
#else
13681494
(void)free_if_fail;
@@ -4442,32 +4568,32 @@ aot_unload(AOTModule *module)
44424568
#if WASM_ENABLE_GC != 0
44434569
uint32 i;
44444570
for (i = 0; i < module->table_count; i++) {
4445-
destroy_init_expr(&module->tables[i].init_expr);
4571+
destroy_init_expr(module, &module->tables[i].init_expr);
44464572
}
44474573
#endif
44484574
destroy_tables(module->tables);
44494575
}
44504576

44514577
if (module->table_init_data_list)
4452-
destroy_table_init_data_list(module->table_init_data_list,
4578+
destroy_table_init_data_list(module, module->table_init_data_list,
44534579
module->table_init_data_count);
44544580

4455-
if (module->types)
4456-
destroy_types(module->types, module->type_count);
4457-
44584581
if (module->import_globals)
44594582
destroy_import_globals(module->import_globals);
44604583

44614584
if (module->globals) {
44624585
#if WASM_ENABLE_GC != 0
44634586
uint32 i;
44644587
for (i = 0; i < module->global_count; i++) {
4465-
destroy_init_expr(&module->globals[i].init_expr);
4588+
destroy_init_expr(module, &module->globals[i].init_expr);
44664589
}
44674590
#endif
44684591
destroy_globals(module->globals);
44694592
}
44704593

4594+
if (module->types)
4595+
destroy_types(module->types, module->type_count);
4596+
44714597
if (module->import_funcs)
44724598
destroy_import_funcs(module->import_funcs);
44734599

0 commit comments

Comments
 (0)