Skip to content

Commit

Permalink
Add global export apis
Browse files Browse the repository at this point in the history
  • Loading branch information
bnason-nf committed May 20, 2024
1 parent 49c9fa3 commit ad39cf9
Show file tree
Hide file tree
Showing 4 changed files with 288 additions and 20 deletions.
89 changes: 69 additions & 20 deletions core/iwasm/aot/aot_runtime.c
Original file line number Diff line number Diff line change
Expand Up @@ -375,58 +375,88 @@ assign_table_init_value(AOTModuleInstance *module_inst, AOTModule *module,
}
#endif /* end of WASM_ENABLE_GC != 0 */

static bool
static WASMGlobalInstance *
global_instantiate(AOTModuleInstance *module_inst, AOTModule *module,
char *error_buf, uint32 error_buf_size)
{
uint32 i;
InitializerExpression *init_expr;
uint8 *p = module_inst->global_data;
AOTImportGlobal *import_global = module->import_globals;
AOTGlobal *global = module->globals;
uint32 global_count = module->import_global_count + module->global_count;
uint64 total_size = sizeof(WASMGlobalInstance) * (uint64)global_count;
WASMGlobalInstance *globals, *global;

if (!(globals = runtime_malloc(total_size, error_buf, error_buf_size))) {
return NULL;
}

/* Initialize import global data */
for (i = 0; i < module->import_global_count; i++, import_global++) {
global = globals;
for (i = 0; i < module->import_global_count;
i++, import_global++, global++) {
bh_assert(import_global->data_offset
== (uint32)(p - module_inst->global_data));
init_global_data(p, import_global->type.val_type,
&import_global->global_data_linked);
global->type = import_global->type.val_type;
global->is_mutable = import_global->type.is_mutable;
#if WASM_ENABLE_GC != 0
/* FIX?: global->ref_type = import_global->ref_type; */
#endif
/* native globals share their initial_values in one module */
bh_memcpy_s(&(global->initial_value), sizeof(WASMValue),
&(import_global->global_data_linked), sizeof(WASMValue));
global->data_offset = import_global->data_offset;

p += import_global->size;
}

/* Initialize defined global data */
for (i = 0; i < module->global_count; i++, global++) {
uint8 flag;
bh_assert(global->data_offset
bh_assert(module->globals[i].data_offset
== (uint32)(p - module_inst->global_data));
init_expr = &global->init_expr;
init_expr = &module->globals[i].init_expr;
flag = init_expr->init_expr_type;

global->type = module->globals[i].type.val_type;
global->is_mutable = module->globals[i].type.is_mutable;
global->data_offset = module->globals[i].data_offset;
#if WASM_ENABLE_GC != 0
/* FIX?: global->ref_type = import_global->ref_type; */
#endif

switch (flag) {
case INIT_EXPR_TYPE_GET_GLOBAL:
{
if (!check_global_init_expr(module, init_expr->u.global_index,
error_buf, error_buf_size)) {
return false;
goto fail;
}
#if WASM_ENABLE_GC == 0
init_global_data(
p, global->type.val_type,
p, module->globals[i].type.val_type,
&module->import_globals[init_expr->u.global_index]
.global_data_linked);
#else
if (init_expr->u.global_index < module->import_global_count) {
init_global_data(
p, global->type.val_type,
p, module->globals[i].type.val_type,
&module->import_globals[init_expr->u.global_index]
.global_data_linked);
}
else {
uint32 global_idx =
init_expr->u.global_index - module->import_global_count;
init_global_data(p, global->type.val_type,
init_global_data(p, module->globals[i].type.val_type,
&module->globals[global_idx].init_expr.u);
}
#endif
bh_memcpy_s(
&(global->initial_value), sizeof(WASMValue),
&(globals[init_expr->u.global_index].initial_value),
sizeof(globals[init_expr->u.global_index].initial_value));
break;
}
#if WASM_ENABLE_GC == 0 && WASM_ENABLE_REF_TYPES != 0
Expand All @@ -453,7 +483,7 @@ global_instantiate(AOTModuleInstance *module_inst, AOTModule *module,
if (!(func_obj =
aot_create_func_obj(module_inst, func_idx, false,
error_buf, error_buf_size))) {
return false;
goto fail;
}
}

Expand All @@ -463,6 +493,7 @@ global_instantiate(AOTModuleInstance *module_inst, AOTModule *module,
case INIT_EXPR_TYPE_I31_NEW:
{
WASMI31ObjectRef i31_obj = wasm_i31_obj_new(init_expr->u.i32);
global->initial_value.gc_obj = (wasm_obj_t)i31_obj;
PUT_REF_TO_ADDR(p, i31_obj);
break;
}
Expand Down Expand Up @@ -490,7 +521,7 @@ global_instantiate(AOTModuleInstance *module_inst, AOTModule *module,
module->type_count, &module->rtt_type_lock))) {
set_error_buf(error_buf, error_buf_size,
"create rtt object failed");
return false;
goto fail;
}

if (!(struct_obj = wasm_struct_obj_new_internal(
Expand All @@ -499,7 +530,7 @@ global_instantiate(AOTModuleInstance *module_inst, AOTModule *module,
rtt_type))) {
set_error_buf(error_buf, error_buf_size,
"create struct object failed");
return false;
goto fail;
}

if (flag == INIT_EXPR_TYPE_STRUCT_NEW) {
Expand All @@ -515,6 +546,8 @@ global_instantiate(AOTModuleInstance *module_inst, AOTModule *module,
}
}

global->initial_value.gc_obj = (void *)struct_obj;

PUT_REF_TO_ADDR(p, struct_obj);
break;
}
Expand Down Expand Up @@ -551,7 +584,7 @@ global_instantiate(AOTModuleInstance *module_inst, AOTModule *module,
module->type_count, &module->rtt_type_lock))) {
set_error_buf(error_buf, error_buf_size,
"create rtt object failed");
return false;
goto fail;
}

if (!(array_obj = wasm_array_obj_new_internal(
Expand All @@ -560,7 +593,7 @@ global_instantiate(AOTModuleInstance *module_inst, AOTModule *module,
rtt_type, len, arr_init_val))) {
set_error_buf(error_buf, error_buf_size,
"create array object failed");
return false;
goto fail;
}

if (flag == INIT_EXPR_TYPE_ARRAY_NEW_FIXED) {
Expand All @@ -575,22 +608,31 @@ global_instantiate(AOTModuleInstance *module_inst, AOTModule *module,
}
}

global->initial_value.gc_obj = (void *)array_obj;

PUT_REF_TO_ADDR(p, array_obj);
break;
}
#endif /* end of WASM_ENABLE_GC != 0 */
default:
{
init_global_data(p, global->type.val_type, &init_expr->u);
init_global_data(p, module->globals[i].type.val_type,
&init_expr->u);
bh_memcpy_s(&(global->initial_value), sizeof(WASMValue),
&(init_expr->u), sizeof(init_expr->u));
break;
}
}
p += global->size;

p += module->globals[i].size;
}

bh_assert(module_inst->global_data_size
== (uint32)(p - module_inst->global_data));
return true;
return globals;
fail:
wasm_runtime_free(globals);
return NULL;
}

static bool
Expand Down Expand Up @@ -1625,8 +1667,11 @@ aot_instantiate(AOTModule *module, AOTModuleInstance *parent,
+ module_inst_mem_inst_size;
module_inst->global_data = p;
module_inst->global_data_size = module->global_data_size;
if (!global_instantiate(module_inst, module, error_buf, error_buf_size))
((AOTModuleInstanceExtra *)module_inst->e)->globals =
global_instantiate(module_inst, module, error_buf, error_buf_size);
if (!((AOTModuleInstanceExtra *)module_inst->e)->globals) {
goto fail;
}

/* Initialize table info */
p += module->global_data_size;
Expand Down Expand Up @@ -1885,8 +1930,9 @@ destroy_c_api_frames(Vector *frames)
void
aot_deinstantiate(AOTModuleInstance *module_inst, bool is_sub_inst)
{
WASMModuleInstanceExtraCommon *common =
&((AOTModuleInstanceExtra *)module_inst->e)->common;
AOTModuleInstanceExtra *e = (AOTModuleInstanceExtra *)module_inst->e;

WASMModuleInstanceExtraCommon *common = &e->common;
if (module_inst->exec_env_singleton) {
/* wasm_exec_env_destroy will call
wasm_cluster_wait_for_all_except_self to wait for other
Expand All @@ -1896,6 +1942,9 @@ aot_deinstantiate(AOTModuleInstance *module_inst, bool is_sub_inst)
wasm_exec_env_destroy((WASMExecEnv *)module_inst->exec_env_singleton);
}

if (e->globals)
wasm_runtime_free(e->globals);

#if WASM_ENABLE_PERF_PROFILING != 0
if (module_inst->func_perf_profilings)
wasm_runtime_free(module_inst->func_perf_profilings);
Expand Down
1 change: 1 addition & 0 deletions core/iwasm/aot/aot_runtime.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ typedef struct AOTFunctionInstance {
typedef struct AOTModuleInstanceExtra {
DefPointer(const uint32 *, stack_sizes);
WASMModuleInstanceExtraCommon common;
WASMGlobalInstance *globals;
#if WASM_ENABLE_MULTI_MODULE != 0
bh_list sub_module_inst_list_head;
bh_list *sub_module_inst_list;
Expand Down
154 changes: 154 additions & 0 deletions core/iwasm/common/wasm_runtime_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -1891,6 +1891,160 @@ wasm_runtime_set_module_inst(WASMExecEnv *exec_env,
wasm_exec_env_set_module_inst(exec_env, module_inst);
}

wasm_global_instance_t
wasm_runtime_get_export_global_instance(wasm_exec_env_t exec_env,
const char *name)
{
#if WASM_ENABLE_INTERP != 0
if (exec_env->module_inst->module_type == Wasm_Module_Bytecode) {
WASMModuleInstance *wasm_module_inst =
(WASMModuleInstance *)exec_env->module_inst;
WASMModule *wasm_module = wasm_module_inst->module;
uint32 i;
for (i = 0; i < wasm_module->export_count; i++) {
const WASMExport *wasm_export = &wasm_module->exports[i];
if ((wasm_export->kind == WASM_IMPORT_EXPORT_KIND_GLOBAL)
&& !strcmp(wasm_export->name, name)) {
WASMModuleInstanceExtra *e =
(WASMModuleInstanceExtra *)wasm_module_inst->e;
return &e->globals[wasm_export->index];
}
}
}
#endif
#if WASM_ENABLE_AOT != 0
if (exec_env->module_inst->module_type == Wasm_Module_AoT) {
AOTModuleInstance *aot_module_inst =
(AOTModuleInstance *)exec_env->module_inst;
AOTModule *aot_module = (AOTModule *)aot_module_inst->module;
uint32 i;
for (i = 0; i < aot_module->export_count; i++) {
const AOTExport *aot_export = &aot_module->exports[i];
if ((aot_export->kind == WASM_IMPORT_EXPORT_KIND_GLOBAL)
&& !strcmp(aot_export->name, name)) {
AOTModuleInstanceExtra *e =
(AOTModuleInstanceExtra *)aot_module_inst->e;
return &e->globals[aot_export->index];
}
}
}
#endif

return NULL;
}

wasm_valkind_t
wasm_runtime_global_instance_get_kind(wasm_global_instance_t global_instance)
{
switch (global_instance->type) {
case VALUE_TYPE_I32:
return WASM_I32;
case VALUE_TYPE_I64:
return WASM_I64;
case VALUE_TYPE_F32:
return WASM_F32;
case VALUE_TYPE_F64:
return WASM_F64;
case VALUE_TYPE_V128:
return WASM_V128;
case VALUE_TYPE_FUNCREF:
bh_assert(0);
return WASM_FUNCREF;
case VALUE_TYPE_EXTERNREF:
case VALUE_TYPE_VOID:
default:
bh_assert(0);
return (wasm_valkind_t)-1;
}
}

bool
wasm_runtime_global_instance_get_mutable(wasm_global_instance_t global_instance)
{
return global_instance->is_mutable;
}

bool
wasm_runtime_global_instance_get_value(wasm_global_instance_t global_instance,
wasm_val_t *value)
{
if (!value) {
bh_assert(0);
return false;
}

memset(value, 0, sizeof(wasm_val_t));

if (!global_instance) {
bh_assert(0);
return false;
}

switch (global_instance->type) {
case VALUE_TYPE_I32:
value->kind = WASM_I32;
value->of.i32 = global_instance->initial_value.i32;
break;
case VALUE_TYPE_I64:
value->kind = WASM_I64;
value->of.i64 = global_instance->initial_value.i64;
break;
case VALUE_TYPE_F32:
value->kind = WASM_F32;
value->of.f32 = global_instance->initial_value.f32;
break;
case VALUE_TYPE_F64:
value->kind = WASM_F64;
value->of.f64 = global_instance->initial_value.f64;
break;
case VALUE_TYPE_V128:
case VALUE_TYPE_FUNCREF:
case VALUE_TYPE_EXTERNREF:
case VALUE_TYPE_VOID:
default:
bh_assert(0);
return false;
}

return true;
}

bool
wasm_runtime_global_instance_set_value(wasm_global_instance_t global_instance,
const wasm_val_t *value)
{
if (!global_instance || !value) {
bh_assert(0);
return false;
}

switch (value->kind) {
case WASM_I32:
global_instance->type = VALUE_TYPE_I32;
global_instance->initial_value.i32 = value->of.i32;
break;
case WASM_I64:
global_instance->type = VALUE_TYPE_I64;
global_instance->initial_value.i64 = value->of.i64;
break;
case WASM_F32:
global_instance->type = VALUE_TYPE_F32;
global_instance->initial_value.f32 = value->of.f32;
break;
case WASM_F64:
global_instance->type = VALUE_TYPE_F64;
global_instance->initial_value.f64 = value->of.f64;
break;
case WASM_V128:
case WASM_FUNCREF:
case WASM_EXTERNREF:
default:
bh_assert(0);
return false;
}

return true;
}
void *
wasm_runtime_get_function_attachment(WASMExecEnv *exec_env)
{
Expand Down
Loading

0 comments on commit ad39cf9

Please sign in to comment.