Skip to content

Commit 8b41ea0

Browse files
authored
Re-org calling post instantiation functions (bytecodealliance#1972)
- Use execute_post_instantiate_functions to call start, _initialize, __post_instantiate, __wasm_call_ctors functions after instantiation - Always call start function for both main instance and sub instance - Only call _initialize and __post_instantiate for main instance - Only call ___wasm_call_ctors for main instance and when bulk memory is enabled and wasi import functions are not found - When hw bound check is enabled, use the existing exec_env_tls to call func for sub instance, and switch exec_env_tls's module inst to current module inst to avoid checking failure and using the wrong module inst
1 parent 0bef627 commit 8b41ea0

File tree

2 files changed

+241
-193
lines changed

2 files changed

+241
-193
lines changed

core/iwasm/aot/aot_runtime.c

Lines changed: 125 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -901,77 +901,149 @@ create_exports(AOTModuleInstance *module_inst, AOTModule *module,
901901
return create_export_funcs(module_inst, module, error_buf, error_buf_size);
902902
}
903903

904-
#if WASM_ENABLE_LIBC_WASI != 0
905-
static bool
906-
execute_initialize_function(AOTModuleInstance *module_inst)
907-
{
908-
AOTFunctionInstance *initialize =
909-
aot_lookup_function(module_inst, "_initialize", NULL);
910-
911-
return !initialize
912-
|| aot_create_exec_env_and_call_function(module_inst, initialize, 0,
913-
NULL);
914-
}
915-
#endif
916-
917-
static bool
918-
execute_post_inst_function(AOTModuleInstance *module_inst)
904+
static AOTFunctionInstance *
905+
lookup_post_instantiate_func(AOTModuleInstance *module_inst,
906+
const char *func_name)
919907
{
920-
AOTFunctionInstance *post_inst_func =
921-
aot_lookup_function(module_inst, "__post_instantiate", "()");
908+
AOTFunctionInstance *func;
909+
AOTFuncType *func_type;
922910

923-
if (!post_inst_func)
911+
if (!(func = aot_lookup_function(module_inst, func_name, NULL)))
924912
/* Not found */
925-
return true;
913+
return NULL;
914+
915+
func_type = func->u.func.func_type;
916+
if (!(func_type->param_count == 0 && func_type->result_count == 0))
917+
/* Not a valid function type, ignore it */
918+
return NULL;
926919

927-
return aot_create_exec_env_and_call_function(module_inst, post_inst_func, 0,
928-
NULL);
920+
return func;
929921
}
930922

931923
static bool
932-
execute_start_function(AOTModuleInstance *module_inst)
924+
execute_post_instantiate_functions(AOTModuleInstance *module_inst,
925+
bool is_sub_inst)
933926
{
934927
AOTModule *module = (AOTModule *)module_inst->module;
935-
WASMExecEnv *exec_env;
936-
typedef void (*F)(WASMExecEnv *);
937-
union {
938-
F f;
939-
void *v;
940-
} u;
941-
942-
if (!module->start_function)
928+
AOTFunctionInstance *initialize_func = NULL;
929+
AOTFunctionInstance *post_inst_func = NULL;
930+
AOTFunctionInstance *call_ctors_func = NULL;
931+
#ifdef OS_ENABLE_HW_BOUND_CHECK
932+
WASMModuleInstanceCommon *module_inst_main = NULL;
933+
WASMExecEnv *exec_env_tls = NULL;
934+
#endif
935+
WASMExecEnv *exec_env = NULL;
936+
bool ret = false;
937+
938+
#if WASM_ENABLE_LIBC_WASI != 0
939+
/*
940+
* WASI reactor instances may assume that _initialize will be called by
941+
* the environment at most once, and that none of their other exports
942+
* are accessed before that call.
943+
*/
944+
if (!is_sub_inst && module->import_wasi_api) {
945+
initialize_func =
946+
lookup_post_instantiate_func(module_inst, "_initialize");
947+
}
948+
#endif
949+
950+
/* Execute possible "__post_instantiate" function if wasm app is
951+
compiled by emsdk's early version */
952+
if (!is_sub_inst) {
953+
post_inst_func =
954+
lookup_post_instantiate_func(module_inst, "__post_instantiate");
955+
}
956+
957+
#if WASM_ENABLE_BULK_MEMORY != 0
958+
/* Only execute the memory init function for main instance since
959+
the data segments will be dropped once initialized */
960+
if (!is_sub_inst
961+
#if WASM_ENABLE_LIBC_WASI != 0
962+
&& !module->import_wasi_api
963+
#endif
964+
) {
965+
call_ctors_func =
966+
lookup_post_instantiate_func(module_inst, "__wasm_call_ctors");
967+
}
968+
#endif
969+
970+
if (!module->start_function && !initialize_func && !post_inst_func
971+
&& !call_ctors_func) {
972+
/* No post instantiation functions to call */
943973
return true;
974+
}
944975

945-
if (!(exec_env =
946-
wasm_exec_env_create((WASMModuleInstanceCommon *)module_inst,
947-
module_inst->default_wasm_stack_size))) {
976+
#ifdef OS_ENABLE_HW_BOUND_CHECK
977+
if (is_sub_inst) {
978+
exec_env = exec_env_tls = wasm_runtime_get_exec_env_tls();
979+
if (exec_env_tls) {
980+
/* Temporarily replace exec_env_tls's module inst to current
981+
module inst to avoid checking failure when calling the
982+
wasm functions, and ensure that the exec_env's module inst
983+
is the correct one. */
984+
module_inst_main = exec_env_tls->module_inst;
985+
exec_env_tls->module_inst = (WASMModuleInstanceCommon *)module_inst;
986+
}
987+
}
988+
#endif
989+
if (!exec_env
990+
&& !(exec_env =
991+
wasm_exec_env_create((WASMModuleInstanceCommon *)module_inst,
992+
module_inst->default_wasm_stack_size))) {
948993
aot_set_exception(module_inst, "allocate memory failed");
949994
return false;
950995
}
951996

952-
u.v = module->start_function;
953-
u.f(exec_env);
997+
/* Execute start function for both main insance and sub instance */
998+
if (module->start_function) {
999+
AOTFunctionInstance start_func = { 0 };
1000+
uint32 func_type_idx;
9541001

955-
wasm_exec_env_destroy(exec_env);
956-
return !aot_get_exception(module_inst);
957-
}
1002+
start_func.func_name = "";
1003+
start_func.func_index = module->start_func_index;
1004+
start_func.is_import_func = false;
1005+
func_type_idx = module->func_type_indexes[module->start_func_index
1006+
- module->import_func_count];
1007+
start_func.u.func.func_type = module->func_types[func_type_idx];
1008+
start_func.u.func.func_ptr = module->start_function;
1009+
if (!aot_call_function(exec_env, &start_func, 0, NULL)) {
1010+
goto fail;
1011+
}
1012+
}
9581013

959-
#if WASM_ENABLE_BULK_MEMORY != 0
960-
static bool
961-
execute_memory_init_function(AOTModuleInstance *module_inst)
962-
{
963-
AOTFunctionInstance *memory_init_func =
964-
aot_lookup_function(module_inst, "__wasm_call_ctors", "()");
1014+
if (initialize_func
1015+
&& !aot_call_function(exec_env, initialize_func, 0, NULL)) {
1016+
goto fail;
1017+
}
9651018

966-
if (!memory_init_func)
967-
/* Not found */
968-
return true;
1019+
if (post_inst_func
1020+
&& !aot_call_function(exec_env, post_inst_func, 0, NULL)) {
1021+
goto fail;
1022+
}
9691023

970-
return aot_create_exec_env_and_call_function(module_inst, memory_init_func,
971-
0, NULL);
972-
}
1024+
if (call_ctors_func
1025+
&& !aot_call_function(exec_env, call_ctors_func, 0, NULL)) {
1026+
goto fail;
1027+
}
1028+
1029+
ret = true;
1030+
1031+
fail:
1032+
#ifdef OS_ENABLE_HW_BOUND_CHECK
1033+
if (is_sub_inst && exec_env_tls) {
1034+
bh_assert(exec_env == exec_env_tls);
1035+
/* Restore the exec_env_tls's module inst */
1036+
exec_env_tls->module_inst = module_inst_main;
1037+
}
1038+
else
1039+
wasm_exec_env_destroy(exec_env);
1040+
#else
1041+
wasm_exec_env_destroy(exec_env);
9731042
#endif
9741043

1044+
return ret;
1045+
}
1046+
9751047
static bool
9761048
check_linked_symbol(AOTModule *module, char *error_buf, uint32 error_buf_size)
9771049
{
@@ -1134,47 +1206,10 @@ aot_instantiate(AOTModule *module, bool is_sub_inst, uint32 stack_size,
11341206
}
11351207
#endif
11361208

1137-
if (!is_sub_inst) {
1138-
if (
1139-
#if WASM_ENABLE_LIBC_WASI != 0
1140-
/*
1141-
* reactor instances may assume that _initialize will be called by
1142-
* the environment at most once, and that none of their other
1143-
* exports are accessed before that call.
1144-
*
1145-
* let the loader decide how to act if there is no _initialize
1146-
* in a reactor
1147-
*/
1148-
!execute_initialize_function(module_inst) ||
1149-
#endif
1150-
/* Execute __post_instantiate function */
1151-
!execute_post_inst_function(module_inst)
1152-
/* Execute the function in "start" section */
1153-
|| !execute_start_function(module_inst)) {
1154-
set_error_buf(error_buf, error_buf_size,
1155-
module_inst->cur_exception);
1156-
goto fail;
1157-
}
1158-
}
1159-
1160-
#if WASM_ENABLE_BULK_MEMORY != 0
1161-
#if WASM_ENABLE_LIBC_WASI != 0
1162-
if (!module->import_wasi_api) {
1163-
#endif
1164-
/* Only execute the memory init function for main instance because
1165-
the data segments will be dropped once initialized.
1166-
*/
1167-
if (!is_sub_inst) {
1168-
if (!execute_memory_init_function(module_inst)) {
1169-
set_error_buf(error_buf, error_buf_size,
1170-
module_inst->cur_exception);
1171-
goto fail;
1172-
}
1173-
}
1174-
#if WASM_ENABLE_LIBC_WASI != 0
1209+
if (!execute_post_instantiate_functions(module_inst, is_sub_inst)) {
1210+
set_error_buf(error_buf, error_buf_size, module_inst->cur_exception);
1211+
goto fail;
11751212
}
1176-
#endif
1177-
#endif
11781213

11791214
#if WASM_ENABLE_MEMORY_TRACING != 0
11801215
wasm_runtime_dump_module_inst_mem_consumption(

0 commit comments

Comments
 (0)