@@ -501,6 +501,8 @@ push_const_expr_stack(ConstExprContext *ctx, uint8 flag, uint8 type,
501501 error_buf, error_buf_size))) {
502502 goto fail;
503503 }
504+ bh_memcpy_s(ctx->stack, (ctx->size + 4) * (uint32)sizeof(InitValue),
505+ ctx->data, ctx->size * (uint32)sizeof(InitValue));
504506 }
505507 ctx->size += 4;
506508 }
@@ -523,6 +525,71 @@ push_const_expr_stack(ConstExprContext *ctx, uint8 flag, uint8 type,
523525 return false;
524526}
525527
528+ #if WASM_ENABLE_GC != 0
529+ static void
530+ destroy_init_expr_data_recursive(WASMModule *module, void *data)
531+ {
532+ WASMStructNewInitValues *struct_init_values =
533+ (WASMStructNewInitValues *)data;
534+ WASMArrayNewInitValues *array_init_values = (WASMArrayNewInitValues *)data;
535+ WASMType *wasm_type;
536+ uint32 i;
537+
538+ if (!data)
539+ return;
540+
541+ wasm_type = module->types[struct_init_values->type_idx];
542+
543+ /* The data can only be type of `WASMStructNewInitValues *`
544+ or `WASMArrayNewInitValues *` */
545+ bh_assert(wasm_type->type_flag == WASM_TYPE_STRUCT
546+ || wasm_type->type_flag == WASM_TYPE_ARRAY);
547+
548+ if (wasm_type->type_flag == WASM_TYPE_STRUCT) {
549+ WASMStructType *struct_type = (WASMStructType *)wasm_type;
550+ WASMRefTypeMap *ref_type_map = struct_type->ref_type_maps;
551+ WASMRefType *ref_type;
552+ uint8 field_type;
553+
554+ for (i = 0; i < struct_init_values->count; i++) {
555+ field_type = struct_type->fields[i].field_type;
556+ if (wasm_is_type_multi_byte_type(field_type))
557+ ref_type = ref_type_map->ref_type;
558+ else
559+ ref_type = NULL;
560+ if (wasm_reftype_is_subtype_of(field_type, ref_type,
561+ REF_TYPE_STRUCTREF, NULL,
562+ module->types, module->type_count)
563+ || wasm_reftype_is_subtype_of(
564+ field_type, ref_type, REF_TYPE_ARRAYREF, NULL,
565+ module->types, module->type_count)) {
566+ destroy_init_expr_data_recursive(
567+ module, struct_init_values->fields[i].data);
568+ }
569+ }
570+ }
571+ else if (wasm_type->type_flag == WASM_TYPE_ARRAY) {
572+ WASMArrayType *array_type = (WASMArrayType *)wasm_type;
573+ WASMRefType *elem_ref_type = array_type->elem_ref_type;
574+ uint8 elem_type = array_type->elem_type;
575+
576+ for (i = 0; i < array_init_values->length; i++) {
577+ if (wasm_reftype_is_subtype_of(elem_type, elem_ref_type,
578+ REF_TYPE_STRUCTREF, NULL,
579+ module->types, module->type_count)
580+ || wasm_reftype_is_subtype_of(
581+ elem_type, elem_ref_type, REF_TYPE_ARRAYREF, NULL,
582+ module->types, module->type_count)) {
583+ destroy_init_expr_data_recursive(
584+ module, array_init_values->elem_data[i].data);
585+ }
586+ }
587+ }
588+
589+ wasm_runtime_free(data);
590+ }
591+ #endif
592+
526593static bool
527594pop_const_expr_stack(ConstExprContext *ctx, uint8 *p_flag, uint8 type,
528595#if WASM_ENABLE_GC != 0
@@ -554,17 +621,6 @@ pop_const_expr_stack(ConstExprContext *ctx, uint8 *p_flag, uint8 type,
554621 " but got other");
555622 goto fail;
556623 }
557-
558- if ((ctx->sp != 0) && (cur_value->flag == WASM_OP_GC_PREFIX)
559- && (cur_value->gc_opcode != WASM_OP_REF_I31)) {
560- /* To reduce complexity, we don't allow initialize struct fields/array
561- * element with references, so struct/array must be at the bottom of the
562- * init value stack */
563- set_error_buf(
564- error_buf, error_buf_size,
565- "struct or array as field is not supported in constant expr");
566- goto fail;
567- }
568624#endif
569625
570626 if (p_flag)
@@ -584,7 +640,7 @@ pop_const_expr_stack(ConstExprContext *ctx, uint8 *p_flag, uint8 type,
584640 && (cur_value->gc_opcode == WASM_OP_STRUCT_NEW
585641 || cur_value->gc_opcode == WASM_OP_ARRAY_NEW
586642 || cur_value->gc_opcode == WASM_OP_ARRAY_NEW_FIXED)) {
587- wasm_runtime_free( cur_value->value.data);
643+ destroy_init_expr_data_recursive(ctx->module, cur_value->value.data);
588644 }
589645 return false;
590646#endif
@@ -601,7 +657,8 @@ destroy_const_expr_stack(ConstExprContext *ctx)
601657 && (ctx->stack[i].gc_opcode == WASM_OP_STRUCT_NEW
602658 || ctx->stack[i].gc_opcode == WASM_OP_ARRAY_NEW
603659 || ctx->stack[i].gc_opcode == WASM_OP_ARRAY_NEW_FIXED)) {
604- wasm_runtime_free(ctx->stack[i].value.data);
660+ destroy_init_expr_data_recursive(ctx->module,
661+ ctx->stack[i].value.data);
605662 }
606663 }
607664#endif
@@ -613,12 +670,12 @@ destroy_const_expr_stack(ConstExprContext *ctx)
613670
614671#if WASM_ENABLE_GC != 0
615672static void
616- destroy_init_expr(InitializerExpression *expr)
673+ destroy_init_expr(WASMModule *module, InitializerExpression *expr)
617674{
618675 if (expr->init_expr_type == INIT_EXPR_TYPE_STRUCT_NEW
619676 || expr->init_expr_type == INIT_EXPR_TYPE_ARRAY_NEW
620677 || expr->init_expr_type == INIT_EXPR_TYPE_ARRAY_NEW_FIXED) {
621- wasm_runtime_free( expr->u.data);
678+ destroy_init_expr_data_recursive(module, expr->u.data);
622679 }
623680}
624681#endif /* end of WASM_ENABLE_GC != 0 */
@@ -941,6 +998,7 @@ load_init_expr(WASMModule *module, const uint8 **p_buf, const uint8 *buf_end,
941998 error_buf, error_buf_size))) {
942999 goto fail;
9431000 }
1001+ struct_init_values->type_idx = type_idx;
9441002 struct_init_values->count = field_count;
9451003
9461004 for (i = field_count; i > 0; i--) {
@@ -963,7 +1021,8 @@ load_init_expr(WASMModule *module, const uint8 **p_buf, const uint8 *buf_end,
9631021 field_ref_type, NULL,
9641022 &struct_init_values->fields[field_idx],
9651023 error_buf, error_buf_size)) {
966- wasm_runtime_free(struct_init_values);
1024+ destroy_init_expr_data_recursive(
1025+ module, struct_init_values);
9671026 goto fail;
9681027 }
9691028 }
@@ -975,7 +1034,8 @@ load_init_expr(WASMModule *module, const uint8 **p_buf, const uint8 *buf_end,
9751034 &const_expr_ctx, flag, cur_ref_type.ref_type,
9761035 &cur_ref_type, (uint8)opcode1, &cur_value,
9771036 error_buf, error_buf_size)) {
978- wasm_runtime_free(struct_init_values);
1037+ destroy_init_expr_data_recursive(
1038+ module, struct_init_values);
9791039 goto fail;
9801040 }
9811041 break;
@@ -1059,7 +1119,8 @@ load_init_expr(WASMModule *module, const uint8 **p_buf, const uint8 *buf_end,
10591119 &const_expr_ctx, NULL, VALUE_TYPE_I32,
10601120 NULL, NULL, &len_val, error_buf,
10611121 error_buf_size)) {
1062- wasm_runtime_free(array_init_values);
1122+ destroy_init_expr_data_recursive(
1123+ module, array_init_values);
10631124 goto fail;
10641125 }
10651126 array_init_values->length = len_val.i32;
@@ -1069,7 +1130,8 @@ load_init_expr(WASMModule *module, const uint8 **p_buf, const uint8 *buf_end,
10691130 elem_ref_type, NULL,
10701131 &array_init_values->elem_data[0],
10711132 error_buf, error_buf_size)) {
1072- wasm_runtime_free(array_init_values);
1133+ destroy_init_expr_data_recursive(
1134+ module, array_init_values);
10731135 goto fail;
10741136 }
10751137
@@ -1100,7 +1162,8 @@ load_init_expr(WASMModule *module, const uint8 **p_buf, const uint8 *buf_end,
11001162 &array_init_values
11011163 ->elem_data[i - 1],
11021164 error_buf, error_buf_size)) {
1103- wasm_runtime_free(array_init_values);
1165+ destroy_init_expr_data_recursive(
1166+ module, array_init_values);
11041167 goto fail;
11051168 }
11061169 }
@@ -1133,7 +1196,8 @@ load_init_expr(WASMModule *module, const uint8 **p_buf, const uint8 *buf_end,
11331196 &cur_ref_type, (uint8)opcode1, &cur_value,
11341197 error_buf, error_buf_size)) {
11351198 if (array_init_values) {
1136- wasm_runtime_free(array_init_values);
1199+ destroy_init_expr_data_recursive(
1200+ module, array_init_values);
11371201 }
11381202 goto fail;
11391203 }
@@ -6669,14 +6733,6 @@ wasm_loader_unload(WASMModule *module)
66696733 }
66706734#endif
66716735
6672- if (module->types) {
6673- for (i = 0; i < module->type_count; i++) {
6674- if (module->types[i])
6675- destroy_wasm_type(module->types[i]);
6676- }
6677- wasm_runtime_free(module->types);
6678- }
6679-
66806736 if (module->imports)
66816737 wasm_runtime_free(module->imports);
66826738
@@ -6718,7 +6774,7 @@ wasm_loader_unload(WASMModule *module)
67186774 if (module->tables) {
67196775#if WASM_ENABLE_GC != 0
67206776 for (i = 0; i < module->table_count; i++) {
6721- destroy_init_expr(&module->tables[i].init_expr);
6777+ destroy_init_expr(module, &module->tables[i].init_expr);
67226778 }
67236779#endif
67246780 wasm_runtime_free(module->tables);
@@ -6730,7 +6786,7 @@ wasm_loader_unload(WASMModule *module)
67306786 if (module->globals) {
67316787#if WASM_ENABLE_GC != 0
67326788 for (i = 0; i < module->global_count; i++) {
6733- destroy_init_expr(&module->globals[i].init_expr);
6789+ destroy_init_expr(module, &module->globals[i].init_expr);
67346790 }
67356791#endif
67366792 wasm_runtime_free(module->globals);
@@ -6756,7 +6812,7 @@ wasm_loader_unload(WASMModule *module)
67566812 uint32 j;
67576813 for (j = 0; j < module->table_segments[i].value_count; j++) {
67586814 destroy_init_expr(
6759- &module->table_segments[i].init_values[j]);
6815+ module, &module->table_segments[i].init_values[j]);
67606816 }
67616817#endif
67626818 wasm_runtime_free(module->table_segments[i].init_values);
@@ -6773,6 +6829,14 @@ wasm_loader_unload(WASMModule *module)
67736829 wasm_runtime_free(module->data_segments);
67746830 }
67756831
6832+ if (module->types) {
6833+ for (i = 0; i < module->type_count; i++) {
6834+ if (module->types[i])
6835+ destroy_wasm_type(module->types[i]);
6836+ }
6837+ wasm_runtime_free(module->types);
6838+ }
6839+
67766840 if (module->const_str_list) {
67776841 StringNode *node = module->const_str_list, *node_next;
67786842 while (node) {
@@ -11654,12 +11718,29 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func,
1165411718
1165511719 case WASM_OP_RETURN:
1165611720 {
11721+ WASMFuncType *func_type = func->func_type;
1165711722 int32 idx;
1165811723 uint8 ret_type;
11659- for (idx = (int32)func->func_type->result_count - 1; idx >= 0;
11724+
11725+ #if WASM_ENABLE_GC != 0
11726+ uint32 j = func_type->ref_type_map_count - 1;
11727+ #endif
11728+ for (idx = (int32)func_type->result_count - 1; idx >= 0;
1166011729 idx--) {
11661- ret_type = *(func->func_type->types
11662- + func->func_type->param_count + idx);
11730+ ret_type =
11731+ *(func_type->types + func_type->param_count + idx);
11732+ #if WASM_ENABLE_GC != 0
11733+ if (wasm_is_type_multi_byte_type(ret_type)) {
11734+ WASMRefType *ref_type =
11735+ func_type->ref_type_maps[j].ref_type;
11736+ bh_assert(func_type->ref_type_maps[j].index
11737+ == func_type->param_count + idx);
11738+ bh_memcpy_s(&wasm_ref_type, sizeof(WASMRefType),
11739+ ref_type,
11740+ wasm_reftype_struct_size(ref_type));
11741+ j--;
11742+ }
11743+ #endif
1166311744#if WASM_ENABLE_FAST_INTERP != 0
1166411745 /* emit the offset after return opcode */
1166511746 POP_OFFSET_TYPE(ret_type);
0 commit comments