|
|
@@ -866,6 +866,174 @@ check_global_init_expr(const WASMModule *module, uint32 global_index,
|
|
|
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.
|
|
|
*/
|
|
|
@@ -964,9 +1132,7 @@ globals_instantiate(WASMModule *module, WASMModuleInstance *module_inst,
|
|
|
case INIT_EXPR_TYPE_STRUCT_NEW:
|
|
|
case INIT_EXPR_TYPE_STRUCT_NEW_DEFAULT:
|
|
|
{
|
|
|
- WASMRttType *rtt_type;
|
|
|
WASMStructObjectRef struct_obj;
|
|
|
- WASMStructType *struct_type;
|
|
|
WASMStructNewInitValues *init_values = NULL;
|
|
|
uint32 type_idx;
|
|
|
|
|
|
@@ -978,36 +1144,13 @@ globals_instantiate(WASMModule *module, WASMModuleInstance *module_inst,
|
|
|
type_idx = init_expr->u.type_index;
|
|
|
}
|
|
|
|
|
|
- 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");
|
|
|
+ struct_obj = instantiate_struct_global_recursive(
|
|
|
+ module, module_inst, type_idx, flag, init_values, error_buf,
|
|
|
+ error_buf_size);
|
|
|
+ if (!struct_obj) {
|
|
|
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;
|
|
|
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_FIXED:
|
|
|
{
|
|
|
- WASMRttType *rtt_type;
|
|
|
WASMArrayObjectRef array_obj;
|
|
|
- WASMArrayType *array_type;
|
|
|
WASMArrayNewInitValues *init_values = NULL;
|
|
|
- WASMValue *arr_init_val = NULL, empty_val = { 0 };
|
|
|
+ WASMValue *array_init_value = NULL, empty_value = { 0 };
|
|
|
uint32 type_idx, len;
|
|
|
|
|
|
if (flag == INIT_EXPR_TYPE_ARRAY_NEW_DEFAULT) {
|
|
|
type_idx = init_expr->u.array_new_default.type_index;
|
|
|
len = init_expr->u.array_new_default.length;
|
|
|
- arr_init_val = &empty_val;
|
|
|
+ array_init_value = &empty_value;
|
|
|
}
|
|
|
else {
|
|
|
init_values = (WASMArrayNewInitValues *)init_expr->u.data;
|
|
|
@@ -1033,42 +1174,15 @@ globals_instantiate(WASMModule *module, WASMModuleInstance *module_inst,
|
|
|
len = init_values->length;
|
|
|
|
|
|
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];
|
|
|
-
|
|
|
- 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");
|
|
|
- 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]);
|
|
|
- }
|
|
|
- }
|
|
|
+ array_obj = instantiate_array_global_recursive(
|
|
|
+ module, module_inst, type_idx, flag, len, array_init_value,
|
|
|
+ init_values, error_buf, error_buf_size);
|
|
|
|
|
|
global->initial_value.gc_obj = (void *)array_obj;
|
|
|
-
|
|
|
break;
|
|
|
}
|
|
|
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;
|
|
|
WASMRttTypeRef rtt_type;
|
|
|
WASMFuncObjectRef func_obj;
|
|
|
- WASMFunctionInstance *func_inst;
|
|
|
WASMFuncType *func_type;
|
|
|
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);
|
|
|
}
|
|
|
|
|
|
- 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",
|
|
|
func_idx);
|
|
|
return NULL;
|
|
|
}
|
|
|
|
|
|
- func_inst = &module_inst->e->functions[func_idx];
|
|
|
- func_type = func_inst->is_import_func ? func_inst->u.func_import->func_type
|
|
|
- : func_inst->u.func->func_type;
|
|
|
- type_idx = func_inst->is_import_func ? func_inst->u.func_import->type_idx
|
|
|
- : func_inst->u.func->type_idx;
|
|
|
+ if (func_idx < module->import_function_count) {
|
|
|
+ func_type = module->import_functions[func_idx].u.function.func_type;
|
|
|
+ type_idx = module->import_functions[func_idx].u.function.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,
|
|
|
module->rtt_types, module->type_count,
|