mirror of
https://github.com/bytecodealliance/wasm-micro-runtime.git
synced 2025-02-06 06:55:07 +00:00
Enhance GC const initializer expression to support nested struct/array new (#3447)
Only support interpreter now, and fix some issues found in wasm loader. This PR fixes issue #3410 and #3411.
This commit is contained in:
parent
403f472ff1
commit
15d191943a
|
@ -250,13 +250,13 @@ typedef union WASMValue {
|
||||||
#endif /* end of WASM_VALUE_DEFINED */
|
#endif /* end of WASM_VALUE_DEFINED */
|
||||||
|
|
||||||
typedef struct WASMStructNewInitValues {
|
typedef struct WASMStructNewInitValues {
|
||||||
uint8 type_idx;
|
uint32 type_idx;
|
||||||
uint32 count;
|
uint32 count;
|
||||||
WASMValue fields[1];
|
WASMValue fields[1];
|
||||||
} WASMStructNewInitValues;
|
} WASMStructNewInitValues;
|
||||||
|
|
||||||
typedef struct WASMArrayNewInitValues {
|
typedef struct WASMArrayNewInitValues {
|
||||||
uint8 type_idx;
|
uint32 type_idx;
|
||||||
uint32 length;
|
uint32 length;
|
||||||
WASMValue elem_data[1];
|
WASMValue elem_data[1];
|
||||||
} WASMArrayNewInitValues;
|
} WASMArrayNewInitValues;
|
||||||
|
|
|
@ -501,6 +501,8 @@ push_const_expr_stack(ConstExprContext *ctx, uint8 flag, uint8 type,
|
||||||
error_buf, error_buf_size))) {
|
error_buf, error_buf_size))) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
bh_memcpy_s(ctx->stack, (ctx->size + 4) * (uint32)sizeof(InitValue),
|
||||||
|
ctx->data, ctx->size * (uint32)sizeof(InitValue));
|
||||||
}
|
}
|
||||||
ctx->size += 4;
|
ctx->size += 4;
|
||||||
}
|
}
|
||||||
|
@ -523,6 +525,71 @@ fail:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if WASM_ENABLE_GC != 0
|
||||||
|
static void
|
||||||
|
destroy_init_expr_data_recursive(WASMModule *module, void *data)
|
||||||
|
{
|
||||||
|
WASMStructNewInitValues *struct_init_values =
|
||||||
|
(WASMStructNewInitValues *)data;
|
||||||
|
WASMArrayNewInitValues *array_init_values = (WASMArrayNewInitValues *)data;
|
||||||
|
WASMType *wasm_type;
|
||||||
|
uint32 i;
|
||||||
|
|
||||||
|
if (!data)
|
||||||
|
return;
|
||||||
|
|
||||||
|
wasm_type = module->types[struct_init_values->type_idx];
|
||||||
|
|
||||||
|
/* 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) {
|
||||||
|
WASMStructType *struct_type = (WASMStructType *)wasm_type;
|
||||||
|
WASMRefTypeMap *ref_type_map = struct_type->ref_type_maps;
|
||||||
|
WASMRefType *ref_type;
|
||||||
|
uint8 field_type;
|
||||||
|
|
||||||
|
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 = ref_type_map->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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
wasm_runtime_free(data);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
pop_const_expr_stack(ConstExprContext *ctx, uint8 *p_flag, uint8 type,
|
pop_const_expr_stack(ConstExprContext *ctx, uint8 *p_flag, uint8 type,
|
||||||
#if WASM_ENABLE_GC != 0
|
#if WASM_ENABLE_GC != 0
|
||||||
|
@ -554,17 +621,6 @@ pop_const_expr_stack(ConstExprContext *ctx, uint8 *p_flag, uint8 type,
|
||||||
" but got other");
|
" but got other");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((ctx->sp != 0) && (cur_value->flag == WASM_OP_GC_PREFIX)
|
|
||||||
&& (cur_value->gc_opcode != WASM_OP_REF_I31)) {
|
|
||||||
/* To reduce complexity, we don't allow initialize struct fields/array
|
|
||||||
* element with references, so struct/array must be at the bottom of the
|
|
||||||
* init value stack */
|
|
||||||
set_error_buf(
|
|
||||||
error_buf, error_buf_size,
|
|
||||||
"struct or array as field is not supported in constant expr");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (p_flag)
|
if (p_flag)
|
||||||
|
@ -584,7 +640,7 @@ fail:
|
||||||
&& (cur_value->gc_opcode == WASM_OP_STRUCT_NEW
|
&& (cur_value->gc_opcode == WASM_OP_STRUCT_NEW
|
||||||
|| cur_value->gc_opcode == WASM_OP_ARRAY_NEW
|
|| cur_value->gc_opcode == WASM_OP_ARRAY_NEW
|
||||||
|| cur_value->gc_opcode == WASM_OP_ARRAY_NEW_FIXED)) {
|
|| cur_value->gc_opcode == WASM_OP_ARRAY_NEW_FIXED)) {
|
||||||
wasm_runtime_free(cur_value->value.data);
|
destroy_init_expr_data_recursive(ctx->module, cur_value->value.data);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
#endif
|
#endif
|
||||||
|
@ -601,7 +657,8 @@ destroy_const_expr_stack(ConstExprContext *ctx)
|
||||||
&& (ctx->stack[i].gc_opcode == WASM_OP_STRUCT_NEW
|
&& (ctx->stack[i].gc_opcode == WASM_OP_STRUCT_NEW
|
||||||
|| ctx->stack[i].gc_opcode == WASM_OP_ARRAY_NEW
|
|| ctx->stack[i].gc_opcode == WASM_OP_ARRAY_NEW
|
||||||
|| ctx->stack[i].gc_opcode == WASM_OP_ARRAY_NEW_FIXED)) {
|
|| ctx->stack[i].gc_opcode == WASM_OP_ARRAY_NEW_FIXED)) {
|
||||||
wasm_runtime_free(ctx->stack[i].value.data);
|
destroy_init_expr_data_recursive(ctx->module,
|
||||||
|
ctx->stack[i].value.data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -613,12 +670,12 @@ destroy_const_expr_stack(ConstExprContext *ctx)
|
||||||
|
|
||||||
#if WASM_ENABLE_GC != 0
|
#if WASM_ENABLE_GC != 0
|
||||||
static void
|
static void
|
||||||
destroy_init_expr(InitializerExpression *expr)
|
destroy_init_expr(WASMModule *module, InitializerExpression *expr)
|
||||||
{
|
{
|
||||||
if (expr->init_expr_type == INIT_EXPR_TYPE_STRUCT_NEW
|
if (expr->init_expr_type == INIT_EXPR_TYPE_STRUCT_NEW
|
||||||
|| expr->init_expr_type == INIT_EXPR_TYPE_ARRAY_NEW
|
|| expr->init_expr_type == INIT_EXPR_TYPE_ARRAY_NEW
|
||||||
|| expr->init_expr_type == INIT_EXPR_TYPE_ARRAY_NEW_FIXED) {
|
|| expr->init_expr_type == INIT_EXPR_TYPE_ARRAY_NEW_FIXED) {
|
||||||
wasm_runtime_free(expr->u.data);
|
destroy_init_expr_data_recursive(module, expr->u.data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* end of WASM_ENABLE_GC != 0 */
|
#endif /* end of WASM_ENABLE_GC != 0 */
|
||||||
|
@ -941,6 +998,7 @@ load_init_expr(WASMModule *module, const uint8 **p_buf, const uint8 *buf_end,
|
||||||
error_buf, error_buf_size))) {
|
error_buf, error_buf_size))) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
struct_init_values->type_idx = type_idx;
|
||||||
struct_init_values->count = field_count;
|
struct_init_values->count = field_count;
|
||||||
|
|
||||||
for (i = field_count; i > 0; i--) {
|
for (i = field_count; i > 0; i--) {
|
||||||
|
@ -963,7 +1021,8 @@ load_init_expr(WASMModule *module, const uint8 **p_buf, const uint8 *buf_end,
|
||||||
field_ref_type, NULL,
|
field_ref_type, NULL,
|
||||||
&struct_init_values->fields[field_idx],
|
&struct_init_values->fields[field_idx],
|
||||||
error_buf, error_buf_size)) {
|
error_buf, error_buf_size)) {
|
||||||
wasm_runtime_free(struct_init_values);
|
destroy_init_expr_data_recursive(
|
||||||
|
module, struct_init_values);
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -975,7 +1034,8 @@ load_init_expr(WASMModule *module, const uint8 **p_buf, const uint8 *buf_end,
|
||||||
&const_expr_ctx, flag, cur_ref_type.ref_type,
|
&const_expr_ctx, flag, cur_ref_type.ref_type,
|
||||||
&cur_ref_type, (uint8)opcode1, &cur_value,
|
&cur_ref_type, (uint8)opcode1, &cur_value,
|
||||||
error_buf, error_buf_size)) {
|
error_buf, error_buf_size)) {
|
||||||
wasm_runtime_free(struct_init_values);
|
destroy_init_expr_data_recursive(
|
||||||
|
module, struct_init_values);
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -1059,7 +1119,8 @@ load_init_expr(WASMModule *module, const uint8 **p_buf, const uint8 *buf_end,
|
||||||
&const_expr_ctx, NULL, VALUE_TYPE_I32,
|
&const_expr_ctx, NULL, VALUE_TYPE_I32,
|
||||||
NULL, NULL, &len_val, error_buf,
|
NULL, NULL, &len_val, error_buf,
|
||||||
error_buf_size)) {
|
error_buf_size)) {
|
||||||
wasm_runtime_free(array_init_values);
|
destroy_init_expr_data_recursive(
|
||||||
|
module, array_init_values);
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
array_init_values->length = len_val.i32;
|
array_init_values->length = len_val.i32;
|
||||||
|
@ -1069,7 +1130,8 @@ load_init_expr(WASMModule *module, const uint8 **p_buf, const uint8 *buf_end,
|
||||||
elem_ref_type, NULL,
|
elem_ref_type, NULL,
|
||||||
&array_init_values->elem_data[0],
|
&array_init_values->elem_data[0],
|
||||||
error_buf, error_buf_size)) {
|
error_buf, error_buf_size)) {
|
||||||
wasm_runtime_free(array_init_values);
|
destroy_init_expr_data_recursive(
|
||||||
|
module, array_init_values);
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1100,7 +1162,8 @@ load_init_expr(WASMModule *module, const uint8 **p_buf, const uint8 *buf_end,
|
||||||
&array_init_values
|
&array_init_values
|
||||||
->elem_data[i - 1],
|
->elem_data[i - 1],
|
||||||
error_buf, error_buf_size)) {
|
error_buf, error_buf_size)) {
|
||||||
wasm_runtime_free(array_init_values);
|
destroy_init_expr_data_recursive(
|
||||||
|
module, array_init_values);
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1133,7 +1196,8 @@ load_init_expr(WASMModule *module, const uint8 **p_buf, const uint8 *buf_end,
|
||||||
&cur_ref_type, (uint8)opcode1, &cur_value,
|
&cur_ref_type, (uint8)opcode1, &cur_value,
|
||||||
error_buf, error_buf_size)) {
|
error_buf, error_buf_size)) {
|
||||||
if (array_init_values) {
|
if (array_init_values) {
|
||||||
wasm_runtime_free(array_init_values);
|
destroy_init_expr_data_recursive(
|
||||||
|
module, array_init_values);
|
||||||
}
|
}
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
@ -6669,14 +6733,6 @@ wasm_loader_unload(WASMModule *module)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (module->types) {
|
|
||||||
for (i = 0; i < module->type_count; i++) {
|
|
||||||
if (module->types[i])
|
|
||||||
destroy_wasm_type(module->types[i]);
|
|
||||||
}
|
|
||||||
wasm_runtime_free(module->types);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (module->imports)
|
if (module->imports)
|
||||||
wasm_runtime_free(module->imports);
|
wasm_runtime_free(module->imports);
|
||||||
|
|
||||||
|
@ -6718,7 +6774,7 @@ wasm_loader_unload(WASMModule *module)
|
||||||
if (module->tables) {
|
if (module->tables) {
|
||||||
#if WASM_ENABLE_GC != 0
|
#if WASM_ENABLE_GC != 0
|
||||||
for (i = 0; i < module->table_count; i++) {
|
for (i = 0; i < module->table_count; i++) {
|
||||||
destroy_init_expr(&module->tables[i].init_expr);
|
destroy_init_expr(module, &module->tables[i].init_expr);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
wasm_runtime_free(module->tables);
|
wasm_runtime_free(module->tables);
|
||||||
|
@ -6730,7 +6786,7 @@ wasm_loader_unload(WASMModule *module)
|
||||||
if (module->globals) {
|
if (module->globals) {
|
||||||
#if WASM_ENABLE_GC != 0
|
#if WASM_ENABLE_GC != 0
|
||||||
for (i = 0; i < module->global_count; i++) {
|
for (i = 0; i < module->global_count; i++) {
|
||||||
destroy_init_expr(&module->globals[i].init_expr);
|
destroy_init_expr(module, &module->globals[i].init_expr);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
wasm_runtime_free(module->globals);
|
wasm_runtime_free(module->globals);
|
||||||
|
@ -6756,7 +6812,7 @@ wasm_loader_unload(WASMModule *module)
|
||||||
uint32 j;
|
uint32 j;
|
||||||
for (j = 0; j < module->table_segments[i].value_count; j++) {
|
for (j = 0; j < module->table_segments[i].value_count; j++) {
|
||||||
destroy_init_expr(
|
destroy_init_expr(
|
||||||
&module->table_segments[i].init_values[j]);
|
module, &module->table_segments[i].init_values[j]);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
wasm_runtime_free(module->table_segments[i].init_values);
|
wasm_runtime_free(module->table_segments[i].init_values);
|
||||||
|
@ -6773,6 +6829,14 @@ wasm_loader_unload(WASMModule *module)
|
||||||
wasm_runtime_free(module->data_segments);
|
wasm_runtime_free(module->data_segments);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (module->types) {
|
||||||
|
for (i = 0; i < module->type_count; i++) {
|
||||||
|
if (module->types[i])
|
||||||
|
destroy_wasm_type(module->types[i]);
|
||||||
|
}
|
||||||
|
wasm_runtime_free(module->types);
|
||||||
|
}
|
||||||
|
|
||||||
if (module->const_str_list) {
|
if (module->const_str_list) {
|
||||||
StringNode *node = module->const_str_list, *node_next;
|
StringNode *node = module->const_str_list, *node_next;
|
||||||
while (node) {
|
while (node) {
|
||||||
|
@ -11654,12 +11718,29 @@ re_scan:
|
||||||
|
|
||||||
case WASM_OP_RETURN:
|
case WASM_OP_RETURN:
|
||||||
{
|
{
|
||||||
|
WASMFuncType *func_type = func->func_type;
|
||||||
int32 idx;
|
int32 idx;
|
||||||
uint8 ret_type;
|
uint8 ret_type;
|
||||||
for (idx = (int32)func->func_type->result_count - 1; idx >= 0;
|
|
||||||
|
#if WASM_ENABLE_GC != 0
|
||||||
|
uint32 j = func_type->ref_type_map_count - 1;
|
||||||
|
#endif
|
||||||
|
for (idx = (int32)func_type->result_count - 1; idx >= 0;
|
||||||
idx--) {
|
idx--) {
|
||||||
ret_type = *(func->func_type->types
|
ret_type =
|
||||||
+ func->func_type->param_count + idx);
|
*(func_type->types + func_type->param_count + idx);
|
||||||
|
#if WASM_ENABLE_GC != 0
|
||||||
|
if (wasm_is_type_multi_byte_type(ret_type)) {
|
||||||
|
WASMRefType *ref_type =
|
||||||
|
func_type->ref_type_maps[j].ref_type;
|
||||||
|
bh_assert(func_type->ref_type_maps[j].index
|
||||||
|
== func_type->param_count + idx);
|
||||||
|
bh_memcpy_s(&wasm_ref_type, sizeof(WASMRefType),
|
||||||
|
ref_type,
|
||||||
|
wasm_reftype_struct_size(ref_type));
|
||||||
|
j--;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
#if WASM_ENABLE_FAST_INTERP != 0
|
#if WASM_ENABLE_FAST_INTERP != 0
|
||||||
/* emit the offset after return opcode */
|
/* emit the offset after return opcode */
|
||||||
POP_OFFSET_TYPE(ret_type);
|
POP_OFFSET_TYPE(ret_type);
|
||||||
|
|
|
@ -866,6 +866,174 @@ check_global_init_expr(const WASMModule *module, uint32 global_index,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if WASM_ENABLE_GC != 0
|
||||||
|
/* Instantiate struct global variable recursively */
|
||||||
|
static WASMStructObjectRef
|
||||||
|
instantiate_struct_global_recursive(WASMModule *module,
|
||||||
|
WASMModuleInstance *module_inst,
|
||||||
|
uint32 type_idx, uint8 flag,
|
||||||
|
WASMStructNewInitValues *init_values,
|
||||||
|
char *error_buf, uint32 error_buf_size)
|
||||||
|
{
|
||||||
|
WASMRttType *rtt_type;
|
||||||
|
WASMStructObjectRef struct_obj;
|
||||||
|
WASMStructType *struct_type;
|
||||||
|
|
||||||
|
struct_type = (WASMStructType *)module->types[type_idx];
|
||||||
|
|
||||||
|
if (!(rtt_type = wasm_rtt_type_new((WASMType *)struct_type, type_idx,
|
||||||
|
module->rtt_types, module->type_count,
|
||||||
|
&module->rtt_type_lock))) {
|
||||||
|
set_error_buf(error_buf, error_buf_size, "create rtt object failed");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(struct_obj = wasm_struct_obj_new_internal(
|
||||||
|
module_inst->e->common.gc_heap_handle, rtt_type))) {
|
||||||
|
set_error_buf(error_buf, error_buf_size, "create struct object failed");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flag == INIT_EXPR_TYPE_STRUCT_NEW) {
|
||||||
|
uint32 field_idx;
|
||||||
|
WASMRefTypeMap *ref_type_map = struct_type->ref_type_maps;
|
||||||
|
|
||||||
|
bh_assert(init_values->count == struct_type->field_count);
|
||||||
|
|
||||||
|
for (field_idx = 0; field_idx < init_values->count; field_idx++) {
|
||||||
|
uint8 field_type = struct_type->fields[field_idx].field_type;
|
||||||
|
WASMRefType *field_ref_type = NULL;
|
||||||
|
if (wasm_is_type_multi_byte_type(field_type)) {
|
||||||
|
field_ref_type = ref_type_map->ref_type;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wasm_reftype_is_subtype_of(field_type, field_ref_type,
|
||||||
|
REF_TYPE_STRUCTREF, NULL,
|
||||||
|
module->types, module->type_count)
|
||||||
|
|| wasm_reftype_is_subtype_of(field_type, field_ref_type,
|
||||||
|
REF_TYPE_ARRAYREF, NULL,
|
||||||
|
module->types, module->type_count)
|
||||||
|
|| wasm_reftype_is_subtype_of(
|
||||||
|
field_type, field_ref_type, REF_TYPE_FUNCREF, NULL,
|
||||||
|
module->types, module->type_count)) {
|
||||||
|
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 field_value = { 0 };
|
||||||
|
|
||||||
|
bh_assert(heap_type >= 0);
|
||||||
|
wasm_type = module->types[heap_type];
|
||||||
|
|
||||||
|
bh_assert(wasm_type->type_flag == WASM_TYPE_STRUCT
|
||||||
|
&& wasm_type->type_flag == WASM_TYPE_ARRAY
|
||||||
|
&& wasm_type->type_flag == WASM_TYPE_FUNC);
|
||||||
|
|
||||||
|
if (wasm_type->type_flag == WASM_TYPE_STRUCT) {
|
||||||
|
WASMStructNewInitValues *init_values1 =
|
||||||
|
(WASMStructNewInitValues *)wasm_value->data;
|
||||||
|
WASMStructObjectRef field =
|
||||||
|
instantiate_struct_global_recursive(
|
||||||
|
module, module_inst, heap_type,
|
||||||
|
init_values1 ? INIT_EXPR_TYPE_STRUCT_NEW
|
||||||
|
: INIT_EXPR_TYPE_STRUCT_NEW_DEFAULT,
|
||||||
|
init_values1, error_buf, error_buf_size);
|
||||||
|
field_value.gc_obj = (WASMObjectRef)field;
|
||||||
|
wasm_struct_obj_set_field(struct_obj, field_idx,
|
||||||
|
&field_value);
|
||||||
|
}
|
||||||
|
else if (wasm_type->type_flag == WASM_TYPE_ARRAY) {
|
||||||
|
/* struct object's field is an array obj */
|
||||||
|
set_error_buf(error_buf, error_buf_size,
|
||||||
|
"array as a field in struct object is "
|
||||||
|
"not supported in constant init expr");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
else if (wasm_type->type_flag == WASM_TYPE_FUNC) {
|
||||||
|
WASMFuncObjectRef func_obj = NULL;
|
||||||
|
/* UINT32_MAX indicates that it is a null reference */
|
||||||
|
if (wasm_value->u32 != UINT32_MAX) {
|
||||||
|
if (!(func_obj = wasm_create_func_obj(
|
||||||
|
module_inst, wasm_value->u32, false,
|
||||||
|
error_buf, error_buf_size))) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
field_value.gc_obj = (WASMObjectRef)func_obj;
|
||||||
|
wasm_struct_obj_set_field(struct_obj, field_idx,
|
||||||
|
&field_value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
wasm_struct_obj_set_field(struct_obj, field_idx,
|
||||||
|
&init_values->fields[field_idx]);
|
||||||
|
}
|
||||||
|
if (wasm_is_type_multi_byte_type(field_type)) {
|
||||||
|
ref_type_map++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return struct_obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
static WASMArrayObjectRef
|
||||||
|
instantiate_array_global_recursive(WASMModule *module,
|
||||||
|
WASMModuleInstance *module_inst,
|
||||||
|
uint32 type_idx, uint8 flag, uint32 len,
|
||||||
|
WASMValue *array_init_value,
|
||||||
|
WASMArrayNewInitValues *init_values,
|
||||||
|
char *error_buf, uint32 error_buf_size)
|
||||||
|
{
|
||||||
|
WASMRttType *rtt_type;
|
||||||
|
WASMArrayObjectRef array_obj;
|
||||||
|
WASMArrayType *array_type;
|
||||||
|
|
||||||
|
array_type = (WASMArrayType *)module->types[type_idx];
|
||||||
|
|
||||||
|
if (!(rtt_type = wasm_rtt_type_new((WASMType *)array_type, type_idx,
|
||||||
|
module->rtt_types, module->type_count,
|
||||||
|
&module->rtt_type_lock))) {
|
||||||
|
set_error_buf(error_buf, error_buf_size, "create rtt object failed");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(array_obj =
|
||||||
|
wasm_array_obj_new_internal(module_inst->e->common.gc_heap_handle,
|
||||||
|
rtt_type, len, array_init_value))) {
|
||||||
|
set_error_buf(error_buf, error_buf_size, "create array object failed");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flag == INIT_EXPR_TYPE_ARRAY_NEW_FIXED) {
|
||||||
|
uint32 elem_idx;
|
||||||
|
uint8 elem_type = array_type->elem_type;
|
||||||
|
WASMRefType *elem_ref_type = array_type->elem_ref_type;
|
||||||
|
|
||||||
|
bh_assert(init_values);
|
||||||
|
|
||||||
|
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)
|
||||||
|
|| wasm_reftype_is_subtype_of(elem_type, elem_ref_type,
|
||||||
|
REF_TYPE_FUNCREF, NULL, module->types,
|
||||||
|
module->type_count)) {
|
||||||
|
/* TODO */
|
||||||
|
}
|
||||||
|
|
||||||
|
for (elem_idx = 0; elem_idx < len; elem_idx++) {
|
||||||
|
wasm_array_obj_set_elem(array_obj, elem_idx,
|
||||||
|
&init_values->elem_data[elem_idx]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return array_obj;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Instantiate globals in a module.
|
* Instantiate globals in a module.
|
||||||
*/
|
*/
|
||||||
|
@ -964,9 +1132,7 @@ globals_instantiate(WASMModule *module, WASMModuleInstance *module_inst,
|
||||||
case INIT_EXPR_TYPE_STRUCT_NEW:
|
case INIT_EXPR_TYPE_STRUCT_NEW:
|
||||||
case INIT_EXPR_TYPE_STRUCT_NEW_DEFAULT:
|
case INIT_EXPR_TYPE_STRUCT_NEW_DEFAULT:
|
||||||
{
|
{
|
||||||
WASMRttType *rtt_type;
|
|
||||||
WASMStructObjectRef struct_obj;
|
WASMStructObjectRef struct_obj;
|
||||||
WASMStructType *struct_type;
|
|
||||||
WASMStructNewInitValues *init_values = NULL;
|
WASMStructNewInitValues *init_values = NULL;
|
||||||
uint32 type_idx;
|
uint32 type_idx;
|
||||||
|
|
||||||
|
@ -978,36 +1144,13 @@ globals_instantiate(WASMModule *module, WASMModuleInstance *module_inst,
|
||||||
type_idx = init_expr->u.type_index;
|
type_idx = init_expr->u.type_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct_type = (WASMStructType *)module->types[type_idx];
|
struct_obj = instantiate_struct_global_recursive(
|
||||||
|
module, module_inst, type_idx, flag, init_values, error_buf,
|
||||||
if (!(rtt_type = wasm_rtt_type_new(
|
error_buf_size);
|
||||||
(WASMType *)struct_type, type_idx, module->rtt_types,
|
if (!struct_obj) {
|
||||||
module->type_count, &module->rtt_type_lock))) {
|
|
||||||
set_error_buf(error_buf, error_buf_size,
|
|
||||||
"create rtt object failed");
|
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(struct_obj = wasm_struct_obj_new_internal(
|
|
||||||
module_inst->e->common.gc_heap_handle, rtt_type))) {
|
|
||||||
set_error_buf(error_buf, error_buf_size,
|
|
||||||
"create struct object failed");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (flag == INIT_EXPR_TYPE_STRUCT_NEW) {
|
|
||||||
uint32 field_idx;
|
|
||||||
|
|
||||||
bh_assert(init_values->count == struct_type->field_count);
|
|
||||||
|
|
||||||
for (field_idx = 0; field_idx < init_values->count;
|
|
||||||
field_idx++) {
|
|
||||||
wasm_struct_obj_set_field(
|
|
||||||
struct_obj, field_idx,
|
|
||||||
&init_values->fields[field_idx]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
global->initial_value.gc_obj = (void *)struct_obj;
|
global->initial_value.gc_obj = (void *)struct_obj;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1015,17 +1158,15 @@ globals_instantiate(WASMModule *module, WASMModuleInstance *module_inst,
|
||||||
case INIT_EXPR_TYPE_ARRAY_NEW_DEFAULT:
|
case INIT_EXPR_TYPE_ARRAY_NEW_DEFAULT:
|
||||||
case INIT_EXPR_TYPE_ARRAY_NEW_FIXED:
|
case INIT_EXPR_TYPE_ARRAY_NEW_FIXED:
|
||||||
{
|
{
|
||||||
WASMRttType *rtt_type;
|
|
||||||
WASMArrayObjectRef array_obj;
|
WASMArrayObjectRef array_obj;
|
||||||
WASMArrayType *array_type;
|
|
||||||
WASMArrayNewInitValues *init_values = NULL;
|
WASMArrayNewInitValues *init_values = NULL;
|
||||||
WASMValue *arr_init_val = NULL, empty_val = { 0 };
|
WASMValue *array_init_value = NULL, empty_value = { 0 };
|
||||||
uint32 type_idx, len;
|
uint32 type_idx, len;
|
||||||
|
|
||||||
if (flag == INIT_EXPR_TYPE_ARRAY_NEW_DEFAULT) {
|
if (flag == INIT_EXPR_TYPE_ARRAY_NEW_DEFAULT) {
|
||||||
type_idx = init_expr->u.array_new_default.type_index;
|
type_idx = init_expr->u.array_new_default.type_index;
|
||||||
len = init_expr->u.array_new_default.length;
|
len = init_expr->u.array_new_default.length;
|
||||||
arr_init_val = &empty_val;
|
array_init_value = &empty_value;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
init_values = (WASMArrayNewInitValues *)init_expr->u.data;
|
init_values = (WASMArrayNewInitValues *)init_expr->u.data;
|
||||||
|
@ -1033,42 +1174,15 @@ globals_instantiate(WASMModule *module, WASMModuleInstance *module_inst,
|
||||||
len = init_values->length;
|
len = init_values->length;
|
||||||
|
|
||||||
if (flag == INIT_EXPR_TYPE_ARRAY_NEW) {
|
if (flag == INIT_EXPR_TYPE_ARRAY_NEW) {
|
||||||
arr_init_val = init_values->elem_data;
|
array_init_value = init_values->elem_data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
array_type = (WASMArrayType *)module->types[type_idx];
|
array_obj = instantiate_array_global_recursive(
|
||||||
|
module, module_inst, type_idx, flag, len, array_init_value,
|
||||||
if (!(rtt_type = wasm_rtt_type_new(
|
init_values, error_buf, error_buf_size);
|
||||||
(WASMType *)array_type, type_idx, module->rtt_types,
|
|
||||||
module->type_count, &module->rtt_type_lock))) {
|
|
||||||
set_error_buf(error_buf, error_buf_size,
|
|
||||||
"create rtt object failed");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(array_obj = wasm_array_obj_new_internal(
|
|
||||||
module_inst->e->common.gc_heap_handle, rtt_type, len,
|
|
||||||
arr_init_val))) {
|
|
||||||
set_error_buf(error_buf, error_buf_size,
|
|
||||||
"create array object failed");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (flag == INIT_EXPR_TYPE_ARRAY_NEW_FIXED) {
|
|
||||||
uint32 elem_idx;
|
|
||||||
|
|
||||||
bh_assert(init_values);
|
|
||||||
|
|
||||||
for (elem_idx = 0; elem_idx < len; elem_idx++) {
|
|
||||||
wasm_array_obj_set_elem(
|
|
||||||
array_obj, elem_idx,
|
|
||||||
&init_values->elem_data[elem_idx]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
global->initial_value.gc_obj = (void *)array_obj;
|
global->initial_value.gc_obj = (void *)array_obj;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case INIT_EXPR_TYPE_I31_NEW:
|
case INIT_EXPR_TYPE_I31_NEW:
|
||||||
|
@ -1704,7 +1818,6 @@ wasm_create_func_obj(WASMModuleInstance *module_inst, uint32 func_idx,
|
||||||
WASMModule *module = module_inst->module;
|
WASMModule *module = module_inst->module;
|
||||||
WASMRttTypeRef rtt_type;
|
WASMRttTypeRef rtt_type;
|
||||||
WASMFuncObjectRef func_obj;
|
WASMFuncObjectRef func_obj;
|
||||||
WASMFunctionInstance *func_inst;
|
|
||||||
WASMFuncType *func_type;
|
WASMFuncType *func_type;
|
||||||
uint32 type_idx;
|
uint32 type_idx;
|
||||||
|
|
||||||
|
@ -1713,17 +1826,22 @@ wasm_create_func_obj(WASMModuleInstance *module_inst, uint32 func_idx,
|
||||||
error_buf_size = sizeof(module_inst->cur_exception);
|
error_buf_size = sizeof(module_inst->cur_exception);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (func_idx >= module_inst->e->function_count) {
|
if (func_idx >= module->import_function_count + module->function_count) {
|
||||||
set_error_buf_v(error_buf, error_buf_size, "unknown function %d",
|
set_error_buf_v(error_buf, error_buf_size, "unknown function %d",
|
||||||
func_idx);
|
func_idx);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
func_inst = &module_inst->e->functions[func_idx];
|
if (func_idx < module->import_function_count) {
|
||||||
func_type = func_inst->is_import_func ? func_inst->u.func_import->func_type
|
func_type = module->import_functions[func_idx].u.function.func_type;
|
||||||
: func_inst->u.func->func_type;
|
type_idx = module->import_functions[func_idx].u.function.type_idx;
|
||||||
type_idx = func_inst->is_import_func ? func_inst->u.func_import->type_idx
|
}
|
||||||
: func_inst->u.func->type_idx;
|
else {
|
||||||
|
func_type = module->functions[func_idx - module->import_function_count]
|
||||||
|
->func_type;
|
||||||
|
type_idx = module->functions[func_idx - module->import_function_count]
|
||||||
|
->type_idx;
|
||||||
|
}
|
||||||
|
|
||||||
if (!(rtt_type = wasm_rtt_type_new((WASMType *)func_type, type_idx,
|
if (!(rtt_type = wasm_rtt_type_new((WASMType *)func_type, type_idx,
|
||||||
module->rtt_types, module->type_count,
|
module->rtt_types, module->type_count,
|
||||||
|
|
Loading…
Reference in New Issue
Block a user