@@ -1150,12 +1150,76 @@ load_memory_info(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
11501150
11511151#if WASM_ENABLE_GC != 0
11521152static 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
11751239static 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+
11921360static bool
11931361load_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,
13621488fail :
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