Skip to content

Commit cc50efb

Browse files
committed
feat: introduce WASMValueWithType for structured value handling and update related functions
1 parent f89bcde commit cc50efb

4 files changed

Lines changed: 112 additions & 67 deletions

File tree

core/iwasm/common/gc/gc_type.h

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -379,6 +379,47 @@ wasm_reftype_set_create(uint32 size);
379379
WASMRefType *
380380
wasm_reftype_set_insert(HashMap *ref_type_set, const WASMRefType *ref_type);
381381

382+
static inline bool
383+
wasm_val_is_struct(WASMValueWithType *value, const WASMTypePtr *types,
384+
uint32 type_count)
385+
{
386+
if (!value) {
387+
return false;
388+
}
389+
390+
if (!wasm_is_type_reftype(value->type)) {
391+
return false;
392+
}
393+
394+
/*
395+
* WASMStructInitValue and WASMArrayInitValue both use REF_TYPE_HT_NULLABLE
396+
* as their type field.
397+
* if in future, value->type uses other type, need to check more conditions
398+
* here
399+
*/
400+
return wasm_reftype_is_subtype_of(REF_TYPE_HT_NULLABLE, &value->ref_type,
401+
REF_TYPE_STRUCTREF, NULL, types,
402+
type_count);
403+
}
404+
405+
static inline bool
406+
wasm_val_is_array(WASMValueWithType *value, const WASMTypePtr *types,
407+
uint32 type_count)
408+
{
409+
if (!value) {
410+
return false;
411+
}
412+
/*
413+
* WASMStructInitValue and WASMArrayInitValue both use REF_TYPE_HT_NULLABLE
414+
* as their type field.
415+
* if in future, value->type uses other type, need to check more conditions
416+
* here
417+
*/
418+
return wasm_reftype_is_subtype_of(REF_TYPE_HT_NULLABLE, &value->ref_type,
419+
REF_TYPE_ARRAYREF, NULL, types,
420+
type_count);
421+
}
422+
382423
#ifdef __cplusplus
383424
} /* end of extern "C" */
384425
#endif

core/iwasm/interpreter/wasm.h

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -267,18 +267,6 @@ typedef union WASMValue {
267267
} WASMValue;
268268
#endif /* end of WASM_VALUE_DEFINED */
269269

270-
typedef struct WASMStructNewInitValues {
271-
uint32 type_idx;
272-
uint32 count;
273-
WASMValue fields[1];
274-
} WASMStructNewInitValues;
275-
276-
typedef struct WASMArrayNewInitValues {
277-
uint32 type_idx;
278-
uint32 length;
279-
WASMValue elem_data[1];
280-
} WASMArrayNewInitValues;
281-
282270
typedef struct InitializerExpression {
283271
/* type of INIT_EXPR_TYPE_XXX, which is an instruction of
284272
constant expression */
@@ -528,6 +516,26 @@ typedef struct WASMArrayType {
528516
typedef void *WASMString;
529517

530518
#endif /* end of WASM_ENABLE_STRINGREF != 0 */
519+
520+
typedef struct WASMValueWithType {
521+
/* VALUE_TYPE_XXX or REF_TYPE_XXX*/
522+
uint8 type;
523+
WASMRefType ref_type;
524+
WASMValue value;
525+
} WASMValueWithType;
526+
527+
typedef struct WASMStructNewInitValues {
528+
uint32 type_idx;
529+
uint32 count;
530+
WASMValueWithType fields[1];
531+
} WASMStructNewInitValues;
532+
533+
typedef struct WASMArrayNewInitValues {
534+
uint32 type_idx;
535+
uint32 length;
536+
WASMValueWithType elem_data[1];
537+
} WASMArrayNewInitValues;
538+
531539
#endif /* end of WASM_ENABLE_GC != 0 */
532540

533541
typedef struct WASMTableType {

core/iwasm/interpreter/wasm_loader.c

Lines changed: 47 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -544,61 +544,52 @@ destroy_init_expr_data_recursive(WASMModule *module, void *data)
544544

545545
/* The data can only be type of `WASMStructNewInitValues *`
546546
or `WASMArrayNewInitValues *` */
547-
bh_assert(wasm_type->type_flag == WASM_TYPE_STRUCT
548-
|| wasm_type->type_flag == WASM_TYPE_ARRAY);
547+
if (wasm_type->type_flag != WASM_TYPE_STRUCT
548+
&& wasm_type->type_flag != WASM_TYPE_ARRAY) {
549+
LOG_ERROR("invalid wasm type flag in destroy_init_expr_data_recursive");
550+
return;
551+
}
549552

550553
if (wasm_type->type_flag == WASM_TYPE_STRUCT) {
551-
WASMStructType *struct_type = (WASMStructType *)wasm_type;
552-
WASMRefType *ref_type;
553-
uint8 field_type;
554-
555-
uint16 ref_type_map_index = 0;
556554
for (i = 0; i < struct_init_values->count; i++) {
557-
field_type = struct_type->fields[i].field_type;
558-
if (wasm_is_type_multi_byte_type(field_type))
559-
ref_type =
560-
struct_type->ref_type_maps[ref_type_map_index++].ref_type;
561-
else
562-
ref_type = NULL;
563-
if (wasm_reftype_is_subtype_of(field_type, ref_type,
564-
REF_TYPE_STRUCTREF, NULL,
565-
module->types, module->type_count)
566-
|| wasm_reftype_is_subtype_of(
567-
field_type, ref_type, REF_TYPE_ARRAYREF, NULL,
568-
module->types, module->type_count)) {
569-
destroy_init_expr_data_recursive(
570-
module, struct_init_values->fields[i].data);
555+
WASMValueWithType *field = &struct_init_values->fields[i];
556+
557+
if (!wasm_val_is_struct(field, module->types,
558+
module->type_count)) {
559+
continue;
571560
}
561+
562+
destroy_init_expr_data_recursive(module, field->value.data);
572563
}
573564
}
574565
else if (wasm_type->type_flag == WASM_TYPE_ARRAY) {
575-
WASMArrayType *array_type = (WASMArrayType *)wasm_type;
576-
WASMRefType *elem_ref_type = array_type->elem_ref_type;
577-
uint8 elem_type = array_type->elem_type;
578-
579566
for (i = 0; i < array_init_values->length; i++) {
580-
if (wasm_reftype_is_subtype_of(elem_type, elem_ref_type,
581-
REF_TYPE_STRUCTREF, NULL,
582-
module->types, module->type_count)
583-
|| wasm_reftype_is_subtype_of(
584-
elem_type, elem_ref_type, REF_TYPE_ARRAYREF, NULL,
585-
module->types, module->type_count)) {
586-
destroy_init_expr_data_recursive(
587-
module, array_init_values->elem_data[i].data);
567+
WASMValueWithType *elem = &array_init_values->elem_data[i];
568+
569+
if (!wasm_val_is_array(elem, module->types,
570+
module->type_count)) {
571+
continue;
588572
}
573+
574+
destroy_init_expr_data_recursive(module, elem->value.data);
589575
}
590576
}
591577

592578
wasm_runtime_free(data);
593579
}
594580
#endif
595581

582+
/*
583+
* Poo top value from const expr stack, and compare its type with the given declared
584+
* type. If match, return the value and actual ref type(if applicable).
585+
*/
596586
static bool
597587
pop_const_expr_stack(ConstExprContext *ctx, uint8 *p_flag, uint8 type,
598588
#if WASM_ENABLE_GC != 0
599-
WASMRefType *ref_type, uint8 *p_gc_opcode,
589+
WASMRefType *declare_ref_type, uint8 *p_gc_opcode,
590+
WASMRefType *p_actual_ref_type,
600591
#endif
601-
WASMValue *p_value,
592+
WASMValue *p_value,
602593
#if WASM_ENABLE_EXTENDED_CONST_EXPR != 0
603594
InitializerExpression **p_expr,
604595
#endif
@@ -621,7 +612,7 @@ pop_const_expr_stack(ConstExprContext *ctx, uint8 *p_flag, uint8 type,
621612
}
622613
#else
623614
if (!wasm_reftype_is_subtype_of(cur_value->type, &cur_value->ref_type, type,
624-
ref_type, ctx->module->types,
615+
declare_ref_type, ctx->module->types,
625616
ctx->module->type_count)) {
626617
set_error_buf_v(error_buf, error_buf_size, "%s%s%s",
627618
"type mismatch: expect ", type2str(type),
@@ -634,6 +625,8 @@ pop_const_expr_stack(ConstExprContext *ctx, uint8 *p_flag, uint8 type,
634625
*p_flag = cur_value->flag;
635626
if (p_value)
636627
*p_value = cur_value->value;
628+
if (p_actual_ref_type)
629+
*p_actual_ref_type = cur_value->ref_type;
637630
#if WASM_ENABLE_GC != 0
638631
if (p_gc_opcode)
639632
*p_gc_opcode = cur_value->gc_opcode;
@@ -891,7 +884,7 @@ load_init_expr(WASMModule *module, const uint8 **p_buf, const uint8 *buf_end,
891884
*/
892885
if (!(pop_const_expr_stack(&const_expr_ctx, &r_flag, value_type,
893886
#if WASM_ENABLE_GC != 0
894-
NULL, NULL,
887+
NULL, NULL, NULL,
895888
#endif
896889
&r_value, &r_expr, error_buf,
897890
error_buf_size))) {
@@ -908,7 +901,7 @@ load_init_expr(WASMModule *module, const uint8 **p_buf, const uint8 *buf_end,
908901

909902
if (!(pop_const_expr_stack(&const_expr_ctx, &l_flag, value_type,
910903
#if WASM_ENABLE_GC != 0
911-
NULL, NULL,
904+
NULL, NULL, NULL,
912905
#endif
913906
&l_value, &l_expr, error_buf,
914907
error_buf_size))) {
@@ -1193,7 +1186,7 @@ load_init_expr(WASMModule *module, const uint8 **p_buf, const uint8 *buf_end,
11931186

11941187
if (!(struct_init_values = loader_malloc(
11951188
offsetof(WASMStructNewInitValues, fields)
1196-
+ (uint64)field_count * sizeof(WASMValue),
1189+
+ (uint64)field_count * sizeof(WASMValueWithType),
11971190
error_buf, error_buf_size))) {
11981191
goto fail;
11991192
}
@@ -1215,10 +1208,11 @@ load_init_expr(WASMModule *module, const uint8 **p_buf, const uint8 *buf_end,
12151208
field_type = VALUE_TYPE_I32;
12161209
}
12171210

1211+
struct_init_values->fields[field_idx].type = field_type;
12181212
if (!pop_const_expr_stack(
12191213
&const_expr_ctx, NULL, field_type,
1220-
field_ref_type, NULL,
1221-
&struct_init_values->fields[field_idx],
1214+
field_ref_type, NULL, &struct_init_values->fields[field_idx].ref_type,
1215+
&struct_init_values->fields[field_idx].value,
12221216
#if WASM_ENABLE_EXTENDED_CONST_EXPR != 0
12231217
NULL,
12241218
#endif
@@ -1320,7 +1314,7 @@ load_init_expr(WASMModule *module, const uint8 **p_buf, const uint8 *buf_end,
13201314

13211315
if (!pop_const_expr_stack(
13221316
&const_expr_ctx, NULL, VALUE_TYPE_I32,
1323-
NULL, NULL, &len_val,
1317+
NULL, NULL, NULL, &len_val,
13241318
#if WASM_ENABLE_EXTENDED_CONST_EXPR != 0
13251319
NULL,
13261320
#endif
@@ -1342,7 +1336,8 @@ load_init_expr(WASMModule *module, const uint8 **p_buf, const uint8 *buf_end,
13421336
if (!pop_const_expr_stack(
13431337
&const_expr_ctx, NULL, elem_type,
13441338
elem_ref_type, NULL,
1345-
&array_init_values->elem_data[0],
1339+
&array_init_values->elem_data[0].ref_type,
1340+
&array_init_values->elem_data[0].value,
13461341
#if WASM_ENABLE_EXTENDED_CONST_EXPR != 0
13471342
NULL,
13481343
#endif
@@ -1376,8 +1371,9 @@ load_init_expr(WASMModule *module, const uint8 **p_buf, const uint8 *buf_end,
13761371
if (!pop_const_expr_stack(
13771372
&const_expr_ctx, NULL, elem_type,
13781373
elem_ref_type, NULL,
1374+
&array_init_values->elem_data[i - 1].ref_type,
13791375
&array_init_values
1380-
->elem_data[i - 1],
1376+
->elem_data[i - 1].value,
13811377
#if WASM_ENABLE_EXTENDED_CONST_EXPR != 0
13821378
NULL,
13831379
#endif
@@ -1399,7 +1395,7 @@ load_init_expr(WASMModule *module, const uint8 **p_buf, const uint8 *buf_end,
13991395
/* POP(i32) */
14001396
if (!pop_const_expr_stack(
14011397
&const_expr_ctx, NULL, VALUE_TYPE_I32, NULL,
1402-
NULL, &len_val,
1398+
NULL, NULL, &len_val,
14031399
#if WASM_ENABLE_EXTENDED_CONST_EXPR != 0
14041400
NULL,
14051401
#endif
@@ -1447,7 +1443,7 @@ load_init_expr(WASMModule *module, const uint8 **p_buf, const uint8 *buf_end,
14471443
{
14481444
/* POP(i32) */
14491445
if (!pop_const_expr_stack(&const_expr_ctx, NULL,
1450-
VALUE_TYPE_I32, NULL, NULL,
1446+
VALUE_TYPE_I32, NULL, NULL, NULL,
14511447
&cur_value,
14521448
#if WASM_ENABLE_EXTENDED_CONST_EXPR != 0
14531449
NULL,
@@ -1496,7 +1492,7 @@ load_init_expr(WASMModule *module, const uint8 **p_buf, const uint8 *buf_end,
14961492
/* There should be only one value left on the init value stack */
14971493
if (!pop_const_expr_stack(&const_expr_ctx, &flag, type,
14981494
#if WASM_ENABLE_GC != 0
1499-
ref_type, &opcode,
1495+
ref_type, &opcode, NULL,
15001496
#endif
15011497
&cur_value,
15021498
#if WASM_ENABLE_EXTENDED_CONST_EXPR != 0
@@ -1920,10 +1916,10 @@ resolve_struct_type(const uint8 **p_buf, const uint8 *buf_end,
19201916
if (need_ref_type_map)
19211917
ref_type_map_count++;
19221918

1923-
if (wasm_is_reftype_anyref(ref_type.ref_type)) {
1924-
LOG_ERROR("Not support using anyref in struct fields");
1925-
return false;
1926-
}
1919+
// if (wasm_is_reftype_anyref(ref_type.ref_type)) {
1920+
// LOG_ERROR("Not support using anyref in struct fields");
1921+
// return false;
1922+
// }
19271923

19281924
if (wasm_is_type_reftype(ref_type.ref_type))
19291925
ref_field_count++;

core/iwasm/interpreter/wasm_runtime.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1050,7 +1050,7 @@ instantiate_struct_global_recursive(WASMModule *module,
10501050
WASMType *wasm_type;
10511051
int32 heap_type =
10521052
ref_type_map->ref_type->ref_ht_common.heap_type;
1053-
WASMValue *wasm_value = &init_values->fields[field_idx];
1053+
WASMValue *wasm_value = &init_values->fields[field_idx].value;
10541054
WASMValue field_value = { 0 };
10551055

10561056
bh_assert(heap_type >= 0);
@@ -1097,7 +1097,7 @@ instantiate_struct_global_recursive(WASMModule *module,
10971097
}
10981098
else {
10991099
wasm_struct_obj_set_field(struct_obj, field_idx,
1100-
&init_values->fields[field_idx]);
1100+
&init_values->fields[field_idx].value);
11011101
}
11021102
if (wasm_is_type_multi_byte_type(field_type)) {
11031103
ref_type_map++;
@@ -1157,7 +1157,7 @@ instantiate_array_global_recursive(WASMModule *module,
11571157

11581158
for (elem_idx = 0; elem_idx < len; elem_idx++) {
11591159
wasm_array_obj_set_elem(array_obj, elem_idx,
1160-
&init_values->elem_data[elem_idx]);
1160+
&init_values->elem_data[elem_idx].value);
11611161
}
11621162
}
11631163

@@ -3200,7 +3200,7 @@ wasm_instantiate(WASMModule *module, WASMModuleInstance *parent,
32003200
len = init_values->length;
32013201

32023202
if (flag == INIT_EXPR_TYPE_ARRAY_NEW_FIXED) {
3203-
arr_init_val = init_values->elem_data;
3203+
arr_init_val = &init_values->elem_data->value;
32043204
}
32053205
}
32063206

0 commit comments

Comments
 (0)