feat: introduce WASMValueWithType for structured value handling and update related functions

This commit is contained in:
liang.he@intel.com 2026-02-01 20:17:11 +08:00
parent f89bcdee02
commit cc50efb1c8
4 changed files with 112 additions and 67 deletions

View File

@ -379,6 +379,47 @@ wasm_reftype_set_create(uint32 size);
WASMRefType *
wasm_reftype_set_insert(HashMap *ref_type_set, const WASMRefType *ref_type);
static inline bool
wasm_val_is_struct(WASMValueWithType *value, const WASMTypePtr *types,
uint32 type_count)
{
if (!value) {
return false;
}
if (!wasm_is_type_reftype(value->type)) {
return false;
}
/*
* WASMStructInitValue and WASMArrayInitValue both use REF_TYPE_HT_NULLABLE
* as their type field.
* if in future, value->type uses other type, need to check more conditions
* here
*/
return wasm_reftype_is_subtype_of(REF_TYPE_HT_NULLABLE, &value->ref_type,
REF_TYPE_STRUCTREF, NULL, types,
type_count);
}
static inline bool
wasm_val_is_array(WASMValueWithType *value, const WASMTypePtr *types,
uint32 type_count)
{
if (!value) {
return false;
}
/*
* WASMStructInitValue and WASMArrayInitValue both use REF_TYPE_HT_NULLABLE
* as their type field.
* if in future, value->type uses other type, need to check more conditions
* here
*/
return wasm_reftype_is_subtype_of(REF_TYPE_HT_NULLABLE, &value->ref_type,
REF_TYPE_ARRAYREF, NULL, types,
type_count);
}
#ifdef __cplusplus
} /* end of extern "C" */
#endif

View File

@ -267,18 +267,6 @@ typedef union WASMValue {
} WASMValue;
#endif /* end of WASM_VALUE_DEFINED */
typedef struct WASMStructNewInitValues {
uint32 type_idx;
uint32 count;
WASMValue fields[1];
} WASMStructNewInitValues;
typedef struct WASMArrayNewInitValues {
uint32 type_idx;
uint32 length;
WASMValue elem_data[1];
} WASMArrayNewInitValues;
typedef struct InitializerExpression {
/* type of INIT_EXPR_TYPE_XXX, which is an instruction of
constant expression */
@ -528,6 +516,26 @@ typedef struct WASMArrayType {
typedef void *WASMString;
#endif /* end of WASM_ENABLE_STRINGREF != 0 */
typedef struct WASMValueWithType {
/* VALUE_TYPE_XXX or REF_TYPE_XXX*/
uint8 type;
WASMRefType ref_type;
WASMValue value;
} WASMValueWithType;
typedef struct WASMStructNewInitValues {
uint32 type_idx;
uint32 count;
WASMValueWithType fields[1];
} WASMStructNewInitValues;
typedef struct WASMArrayNewInitValues {
uint32 type_idx;
uint32 length;
WASMValueWithType elem_data[1];
} WASMArrayNewInitValues;
#endif /* end of WASM_ENABLE_GC != 0 */
typedef struct WASMTableType {

View File

@ -544,48 +544,34 @@ destroy_init_expr_data_recursive(WASMModule *module, void *data)
/* 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
&& wasm_type->type_flag != WASM_TYPE_ARRAY) {
LOG_ERROR("invalid wasm type flag in destroy_init_expr_data_recursive");
return;
}
if (wasm_type->type_flag == WASM_TYPE_STRUCT) {
WASMStructType *struct_type = (WASMStructType *)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);
WASMValueWithType *field = &struct_init_values->fields[i];
if (!wasm_val_is_struct(field, module->types,
module->type_count)) {
continue;
}
destroy_init_expr_data_recursive(module, field->value.data);
}
}
else if (wasm_type->type_flag == WASM_TYPE_ARRAY) {
WASMArrayType *array_type = (WASMArrayType *)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);
WASMValueWithType *elem = &array_init_values->elem_data[i];
if (!wasm_val_is_array(elem, module->types,
module->type_count)) {
continue;
}
destroy_init_expr_data_recursive(module, elem->value.data);
}
}
@ -593,12 +579,17 @@ destroy_init_expr_data_recursive(WASMModule *module, void *data)
}
#endif
/*
* Poo top value from const expr stack, and compare its type with the given declared
* type. If match, return the value and actual ref type(if applicable).
*/
static bool
pop_const_expr_stack(ConstExprContext *ctx, uint8 *p_flag, uint8 type,
#if WASM_ENABLE_GC != 0
WASMRefType *ref_type, uint8 *p_gc_opcode,
WASMRefType *declare_ref_type, uint8 *p_gc_opcode,
WASMRefType *p_actual_ref_type,
#endif
WASMValue *p_value,
WASMValue *p_value,
#if WASM_ENABLE_EXTENDED_CONST_EXPR != 0
InitializerExpression **p_expr,
#endif
@ -621,7 +612,7 @@ pop_const_expr_stack(ConstExprContext *ctx, uint8 *p_flag, uint8 type,
}
#else
if (!wasm_reftype_is_subtype_of(cur_value->type, &cur_value->ref_type, type,
ref_type, ctx->module->types,
declare_ref_type, ctx->module->types,
ctx->module->type_count)) {
set_error_buf_v(error_buf, error_buf_size, "%s%s%s",
"type mismatch: expect ", type2str(type),
@ -634,6 +625,8 @@ pop_const_expr_stack(ConstExprContext *ctx, uint8 *p_flag, uint8 type,
*p_flag = cur_value->flag;
if (p_value)
*p_value = cur_value->value;
if (p_actual_ref_type)
*p_actual_ref_type = cur_value->ref_type;
#if WASM_ENABLE_GC != 0
if (p_gc_opcode)
*p_gc_opcode = cur_value->gc_opcode;
@ -891,7 +884,7 @@ load_init_expr(WASMModule *module, const uint8 **p_buf, const uint8 *buf_end,
*/
if (!(pop_const_expr_stack(&const_expr_ctx, &r_flag, value_type,
#if WASM_ENABLE_GC != 0
NULL, NULL,
NULL, NULL, NULL,
#endif
&r_value, &r_expr, error_buf,
error_buf_size))) {
@ -908,7 +901,7 @@ load_init_expr(WASMModule *module, const uint8 **p_buf, const uint8 *buf_end,
if (!(pop_const_expr_stack(&const_expr_ctx, &l_flag, value_type,
#if WASM_ENABLE_GC != 0
NULL, NULL,
NULL, NULL, NULL,
#endif
&l_value, &l_expr, error_buf,
error_buf_size))) {
@ -1193,7 +1186,7 @@ load_init_expr(WASMModule *module, const uint8 **p_buf, const uint8 *buf_end,
if (!(struct_init_values = loader_malloc(
offsetof(WASMStructNewInitValues, fields)
+ (uint64)field_count * sizeof(WASMValue),
+ (uint64)field_count * sizeof(WASMValueWithType),
error_buf, error_buf_size))) {
goto fail;
}
@ -1215,10 +1208,11 @@ load_init_expr(WASMModule *module, const uint8 **p_buf, const uint8 *buf_end,
field_type = VALUE_TYPE_I32;
}
struct_init_values->fields[field_idx].type = field_type;
if (!pop_const_expr_stack(
&const_expr_ctx, NULL, field_type,
field_ref_type, NULL,
&struct_init_values->fields[field_idx],
field_ref_type, NULL, &struct_init_values->fields[field_idx].ref_type,
&struct_init_values->fields[field_idx].value,
#if WASM_ENABLE_EXTENDED_CONST_EXPR != 0
NULL,
#endif
@ -1320,7 +1314,7 @@ load_init_expr(WASMModule *module, const uint8 **p_buf, const uint8 *buf_end,
if (!pop_const_expr_stack(
&const_expr_ctx, NULL, VALUE_TYPE_I32,
NULL, NULL, &len_val,
NULL, NULL, NULL, &len_val,
#if WASM_ENABLE_EXTENDED_CONST_EXPR != 0
NULL,
#endif
@ -1342,7 +1336,8 @@ load_init_expr(WASMModule *module, const uint8 **p_buf, const uint8 *buf_end,
if (!pop_const_expr_stack(
&const_expr_ctx, NULL, elem_type,
elem_ref_type, NULL,
&array_init_values->elem_data[0],
&array_init_values->elem_data[0].ref_type,
&array_init_values->elem_data[0].value,
#if WASM_ENABLE_EXTENDED_CONST_EXPR != 0
NULL,
#endif
@ -1376,8 +1371,9 @@ load_init_expr(WASMModule *module, const uint8 **p_buf, const uint8 *buf_end,
if (!pop_const_expr_stack(
&const_expr_ctx, NULL, elem_type,
elem_ref_type, NULL,
&array_init_values->elem_data[i - 1].ref_type,
&array_init_values
->elem_data[i - 1],
->elem_data[i - 1].value,
#if WASM_ENABLE_EXTENDED_CONST_EXPR != 0
NULL,
#endif
@ -1399,7 +1395,7 @@ load_init_expr(WASMModule *module, const uint8 **p_buf, const uint8 *buf_end,
/* POP(i32) */
if (!pop_const_expr_stack(
&const_expr_ctx, NULL, VALUE_TYPE_I32, NULL,
NULL, &len_val,
NULL, NULL, &len_val,
#if WASM_ENABLE_EXTENDED_CONST_EXPR != 0
NULL,
#endif
@ -1447,7 +1443,7 @@ load_init_expr(WASMModule *module, const uint8 **p_buf, const uint8 *buf_end,
{
/* POP(i32) */
if (!pop_const_expr_stack(&const_expr_ctx, NULL,
VALUE_TYPE_I32, NULL, NULL,
VALUE_TYPE_I32, NULL, NULL, NULL,
&cur_value,
#if WASM_ENABLE_EXTENDED_CONST_EXPR != 0
NULL,
@ -1496,7 +1492,7 @@ load_init_expr(WASMModule *module, const uint8 **p_buf, const uint8 *buf_end,
/* There should be only one value left on the init value stack */
if (!pop_const_expr_stack(&const_expr_ctx, &flag, type,
#if WASM_ENABLE_GC != 0
ref_type, &opcode,
ref_type, &opcode, NULL,
#endif
&cur_value,
#if WASM_ENABLE_EXTENDED_CONST_EXPR != 0
@ -1920,10 +1916,10 @@ resolve_struct_type(const uint8 **p_buf, const uint8 *buf_end,
if (need_ref_type_map)
ref_type_map_count++;
if (wasm_is_reftype_anyref(ref_type.ref_type)) {
LOG_ERROR("Not support using anyref in struct fields");
return false;
}
// if (wasm_is_reftype_anyref(ref_type.ref_type)) {
// LOG_ERROR("Not support using anyref in struct fields");
// return false;
// }
if (wasm_is_type_reftype(ref_type.ref_type))
ref_field_count++;

View File

@ -1050,7 +1050,7 @@ instantiate_struct_global_recursive(WASMModule *module,
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 *wasm_value = &init_values->fields[field_idx].value;
WASMValue field_value = { 0 };
bh_assert(heap_type >= 0);
@ -1097,7 +1097,7 @@ instantiate_struct_global_recursive(WASMModule *module,
}
else {
wasm_struct_obj_set_field(struct_obj, field_idx,
&init_values->fields[field_idx]);
&init_values->fields[field_idx].value);
}
if (wasm_is_type_multi_byte_type(field_type)) {
ref_type_map++;
@ -1157,7 +1157,7 @@ instantiate_array_global_recursive(WASMModule *module,
for (elem_idx = 0; elem_idx < len; elem_idx++) {
wasm_array_obj_set_elem(array_obj, elem_idx,
&init_values->elem_data[elem_idx]);
&init_values->elem_data[elem_idx].value);
}
}
@ -3200,7 +3200,7 @@ wasm_instantiate(WASMModule *module, WASMModuleInstance *parent,
len = init_values->length;
if (flag == INIT_EXPR_TYPE_ARRAY_NEW_FIXED) {
arr_init_val = init_values->elem_data;
arr_init_val = &init_values->elem_data->value;
}
}