Skip to content

Commit b8e57c6

Browse files
committed
Allow finer control of start function on instantiation
Tries to address #4047. Before this change, wasm_runtime_instantiate would execute the start function unconditionally, correctly implementing the spec. However, if there is an infinite loop in the start function, there was no way to interrupt execution. This change introduces a parameter to InstantiationArgs indicating whether the start function should be immediately invoked. If not, wasm_runtime_instantiate returns a module instance that is initialized except for the start function. This change adds a wasm_runtime_instantiate_run_start_func function which performs this last instantiation step. The user may prepare a timeout in advance of calling this to guard against expensive/infinite loops. This change also demonstrates a possible technique for doing this in iwasm.c.
1 parent 7b724e2 commit b8e57c6

File tree

9 files changed

+135
-46
lines changed

9 files changed

+135
-46
lines changed

core/iwasm/common/wasm_runtime_common.c

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1622,13 +1622,24 @@ wasm_runtime_instantiate_internal(WASMModuleCommon *module,
16221622
WASMModuleInstanceCommon *parent,
16231623
WASMExecEnv *exec_env_main, uint32 stack_size,
16241624
uint32 heap_size, uint32 max_memory_pages,
1625-
char *error_buf, uint32 error_buf_size)
1625+
bool run_start_function, char *error_buf,
1626+
uint32 error_buf_size)
16261627
{
16271628
#if WASM_ENABLE_INTERP != 0
1628-
if (module->module_type == Wasm_Module_Bytecode)
1629-
return (WASMModuleInstanceCommon *)wasm_instantiate(
1630-
(WASMModule *)module, (WASMModuleInstance *)parent, exec_env_main,
1631-
stack_size, heap_size, max_memory_pages, error_buf, error_buf_size);
1629+
if (module->module_type == Wasm_Module_Bytecode) {
1630+
if (run_start_function) {
1631+
return (WASMModuleInstanceCommon *)wasm_instantiate(
1632+
(WASMModule *)module, (WASMModuleInstance *)parent,
1633+
exec_env_main, stack_size, heap_size, max_memory_pages,
1634+
error_buf, error_buf_size);
1635+
}
1636+
1637+
return (WASMModuleInstanceCommon *)
1638+
wasm_instantiate_without_start_function(
1639+
(WASMModule *)module, (WASMModuleInstance *)parent,
1640+
exec_env_main, stack_size, heap_size, max_memory_pages,
1641+
error_buf, error_buf_size);
1642+
}
16321643
#endif
16331644
#if WASM_ENABLE_AOT != 0
16341645
if (module->module_type == Wasm_Module_AoT)
@@ -1647,7 +1658,7 @@ wasm_runtime_instantiate(WASMModuleCommon *module, uint32 stack_size,
16471658
uint32 error_buf_size)
16481659
{
16491660
return wasm_runtime_instantiate_internal(module, NULL, NULL, stack_size,
1650-
heap_size, 0, error_buf,
1661+
heap_size, 0, true, error_buf,
16511662
error_buf_size);
16521663
}
16531664

@@ -1658,8 +1669,8 @@ wasm_runtime_instantiate_ex(WASMModuleCommon *module,
16581669
{
16591670
return wasm_runtime_instantiate_internal(
16601671
module, NULL, NULL, args->default_stack_size,
1661-
args->host_managed_heap_size, args->max_memory_pages, error_buf,
1662-
error_buf_size);
1672+
args->host_managed_heap_size, args->max_memory_pages,
1673+
args->run_start_function, error_buf, error_buf_size);
16631674
}
16641675

16651676
void
@@ -7562,7 +7573,7 @@ wasm_runtime_sub_module_instantiate(WASMModuleCommon *module,
75627573
WASMModuleInstanceCommon *sub_module_inst = NULL;
75637574
sub_module_inst = wasm_runtime_instantiate_internal(
75647575
sub_module, NULL, NULL, stack_size, heap_size, max_memory_pages,
7565-
error_buf, error_buf_size);
7576+
true, error_buf, error_buf_size);
75667577
if (!sub_module_inst) {
75677578
LOG_DEBUG("instantiate %s failed",
75687579
sub_module_list_node->module_name);

core/iwasm/common/wasm_runtime_common.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -575,7 +575,8 @@ wasm_runtime_instantiate_internal(WASMModuleCommon *module,
575575
WASMModuleInstanceCommon *parent,
576576
WASMExecEnv *exec_env_main, uint32 stack_size,
577577
uint32 heap_size, uint32 max_memory_pages,
578-
char *error_buf, uint32 error_buf_size);
578+
bool run_start_function, char *error_buf,
579+
uint32 error_buf_size);
579580

580581
/* Internal API */
581582
void

core/iwasm/include/wasm_export.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,8 @@ typedef struct InstantiationArgs {
273273
uint32_t default_stack_size;
274274
uint32_t host_managed_heap_size;
275275
uint32_t max_memory_pages;
276+
277+
bool run_start_function;
276278
} InstantiationArgs;
277279
#endif /* INSTANTIATION_ARGS_OPTION_DEFINED */
278280

@@ -719,6 +721,17 @@ wasm_runtime_instantiate_ex(const wasm_module_t module,
719721
const InstantiationArgs *args, char *error_buf,
720722
uint32_t error_buf_size);
721723

724+
/**
725+
* Run the start function of an otherwise instantiated module. See
726+
* InstantiationArgs.run_start_function.
727+
*/
728+
WASM_RUNTIME_API_EXTERN bool
729+
wasm_runtime_instantiate_run_start_func(wasm_module_inst_t module,
730+
wasm_module_inst_t parent,
731+
wasm_exec_env_t exec_env,
732+
char *error_buf,
733+
uint32_t error_buf_size);
734+
722735
/**
723736
* Set the running mode of a WASM module instance, override the
724737
* default running mode of the runtime. Note that it only makes sense when

core/iwasm/interpreter/wasm_runtime.c

Lines changed: 54 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2333,6 +2333,25 @@ wasm_set_running_mode(WASMModuleInstance *module_inst, RunningMode running_mode)
23332333
return set_running_mode(module_inst, running_mode, false);
23342334
}
23352335

2336+
bool
2337+
wasm_runtime_instantiate_run_start_func(wasm_module_inst_t module_inst,
2338+
wasm_module_inst_t parent,
2339+
wasm_exec_env_t exec_env,
2340+
char *error_buf,
2341+
uint32_t error_buf_size)
2342+
{
2343+
const bool is_sub_inst = parent != NULL;
2344+
if (!execute_post_instantiate_functions((WASMModuleInstance *)module_inst,
2345+
is_sub_inst, exec_env)) {
2346+
set_error_buf(error_buf, error_buf_size,
2347+
((WASMModuleInstance *)module_inst)->cur_exception);
2348+
wasm_runtime_deinstantiate(module_inst);
2349+
return false;
2350+
}
2351+
2352+
return true;
2353+
}
2354+
23362355
/**
23372356
* Instantiate module
23382357
*/
@@ -2341,6 +2360,41 @@ wasm_instantiate(WASMModule *module, WASMModuleInstance *parent,
23412360
WASMExecEnv *exec_env_main, uint32 stack_size,
23422361
uint32 heap_size, uint32 max_memory_pages, char *error_buf,
23432362
uint32 error_buf_size)
2363+
{
2364+
WASMModuleInstance *module_inst = wasm_instantiate_without_start_function(
2365+
module, parent, exec_env_main, stack_size, heap_size, max_memory_pages,
2366+
error_buf, error_buf_size);
2367+
2368+
if (!module_inst) {
2369+
// wasm_instantiate_without_start_function will deinstantiate on
2370+
// failure.
2371+
return NULL;
2372+
}
2373+
2374+
if (!wasm_runtime_instantiate_run_start_func(
2375+
(WASMModuleInstanceCommon *)module_inst,
2376+
(WASMModuleInstanceCommon *)parent, exec_env_main, error_buf,
2377+
error_buf_size)) {
2378+
// run_start_func will deinstantiate on failure.
2379+
set_error_buf(error_buf, error_buf_size, module_inst->cur_exception);
2380+
return NULL;
2381+
}
2382+
2383+
#if WASM_ENABLE_MEMORY_TRACING != 0
2384+
wasm_runtime_dump_module_inst_mem_consumption(
2385+
(WASMModuleInstanceCommon *)module_inst);
2386+
#endif
2387+
2388+
return module_inst;
2389+
}
2390+
2391+
WASMModuleInstance *
2392+
wasm_instantiate_without_start_function(WASMModule *module,
2393+
WASMModuleInstance *parent,
2394+
WASMExecEnv *exec_env_main,
2395+
uint32 stack_size, uint32 heap_size,
2396+
uint32 max_memory_pages,
2397+
char *error_buf, uint32 error_buf_size)
23442398
{
23452399
WASMModuleInstance *module_inst;
23462400
WASMGlobalInstance *globals = NULL, *global;
@@ -3257,17 +3311,6 @@ wasm_instantiate(WASMModule *module, WASMModuleInstance *parent,
32573311
&module_inst->e->functions[module->start_function];
32583312
}
32593313

3260-
if (!execute_post_instantiate_functions(module_inst, is_sub_inst,
3261-
exec_env_main)) {
3262-
set_error_buf(error_buf, error_buf_size, module_inst->cur_exception);
3263-
goto fail;
3264-
}
3265-
3266-
#if WASM_ENABLE_MEMORY_TRACING != 0
3267-
wasm_runtime_dump_module_inst_mem_consumption(
3268-
(WASMModuleInstanceCommon *)module_inst);
3269-
#endif
3270-
32713314
(void)global_data_end;
32723315
return module_inst;
32733316

core/iwasm/interpreter/wasm_runtime.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -543,6 +543,14 @@ bool
543543
wasm_resolve_import_func(const WASMModule *module,
544544
WASMFunctionImport *function);
545545

546+
WASMModuleInstance *
547+
wasm_instantiate_without_start_function(WASMModule *module,
548+
WASMModuleInstance *parent,
549+
WASMExecEnv *exec_env_main,
550+
uint32 stack_size, uint32 heap_size,
551+
uint32 max_memory_pages,
552+
char *error_buf, uint32 error_buf_size);
553+
546554
WASMModuleInstance *
547555
wasm_instantiate(WASMModule *module, WASMModuleInstance *parent,
548556
WASMExecEnv *exec_env_main, uint32 stack_size,

core/iwasm/libraries/lib-pthread/lib_pthread_wrapper.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -580,7 +580,7 @@ pthread_create_wrapper(wasm_exec_env_t exec_env,
580580
#endif
581581

582582
if (!(new_module_inst = wasm_runtime_instantiate_internal(
583-
module, module_inst, exec_env, stack_size, 0, 0, NULL, 0)))
583+
module, module_inst, exec_env, stack_size, 0, 0, true, NULL, 0)))
584584
return -1;
585585

586586
/* Set custom_data to new module instance */

core/iwasm/libraries/lib-wasi-threads/lib_wasi_threads_wrapper.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ thread_spawn_wrapper(wasm_exec_env_t exec_env, uint32 start_arg)
8787
stack_size = ((WASMModuleInstance *)module_inst)->default_wasm_stack_size;
8888

8989
if (!(new_module_inst = wasm_runtime_instantiate_internal(
90-
module, module_inst, exec_env, stack_size, 0, 0, NULL, 0)))
90+
module, module_inst, exec_env, stack_size, 0, 0, true, NULL, 0)))
9191
return -1;
9292

9393
wasm_runtime_set_custom_data_internal(

core/iwasm/libraries/thread-mgr/thread_manager.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -506,7 +506,8 @@ wasm_cluster_spawn_exec_env(WASMExecEnv *exec_env)
506506
}
507507

508508
if (!(new_module_inst = wasm_runtime_instantiate_internal(
509-
module, module_inst, exec_env, stack_size, 0, 0, NULL, 0))) {
509+
module, module_inst, exec_env, stack_size, 0, 0, true, NULL,
510+
0))) {
510511
return NULL;
511512
}
512513

product-mini/platforms/posix/main.c

Lines changed: 34 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -945,10 +945,38 @@ main(int argc, char *argv[])
945945
libc_wasi_init(wasm_module, argc, argv, &wasi_parse_ctx);
946946
#endif
947947

948+
InstantiationArgs args = {
949+
.default_stack_size = stack_size,
950+
.host_managed_heap_size = heap_size,
951+
.max_memory_pages = 0,
952+
.run_start_function = false,
953+
};
954+
948955
/* instantiate the module */
949-
if (!(wasm_module_inst =
950-
wasm_runtime_instantiate(wasm_module, stack_size, heap_size,
951-
error_buf, sizeof(error_buf)))) {
956+
if (!(wasm_module_inst = wasm_runtime_instantiate_ex(
957+
wasm_module, &args, error_buf, sizeof(error_buf)))) {
958+
printf("%s\n", error_buf);
959+
goto fail3;
960+
}
961+
962+
#if WASM_ENABLE_THREAD_MGR != 0
963+
struct timeout_arg timeout_arg;
964+
korp_tid timeout_tid;
965+
if (timeout_ms >= 0) {
966+
timeout_arg.timeout_ms = timeout_ms;
967+
timeout_arg.inst = wasm_module_inst;
968+
timeout_arg.cancel = false;
969+
ret = os_thread_create(&timeout_tid, timeout_thread, &timeout_arg,
970+
APP_THREAD_STACK_SIZE_DEFAULT);
971+
if (ret != 0) {
972+
printf("Failed to start timeout\n");
973+
goto fail4;
974+
}
975+
}
976+
#endif
977+
978+
if (!wasm_runtime_instantiate_run_start_func(
979+
wasm_module_inst, NULL, NULL, error_buf, sizeof(error_buf))) {
952980
printf("%s\n", error_buf);
953981
goto fail3;
954982
}
@@ -966,27 +994,11 @@ main(int argc, char *argv[])
966994
uint32_t debug_port;
967995
if (exec_env == NULL) {
968996
printf("%s\n", wasm_runtime_get_exception(wasm_module_inst));
969-
goto fail4;
997+
goto fail5;
970998
}
971999
debug_port = wasm_runtime_start_debug_instance(exec_env);
9721000
if (debug_port == 0) {
9731001
printf("Failed to start debug instance\n");
974-
goto fail4;
975-
}
976-
}
977-
#endif
978-
979-
#if WASM_ENABLE_THREAD_MGR != 0
980-
struct timeout_arg timeout_arg;
981-
korp_tid timeout_tid;
982-
if (timeout_ms >= 0) {
983-
timeout_arg.timeout_ms = timeout_ms;
984-
timeout_arg.inst = wasm_module_inst;
985-
timeout_arg.cancel = false;
986-
ret = os_thread_create(&timeout_tid, timeout_thread, &timeout_arg,
987-
APP_THREAD_STACK_SIZE_DEFAULT);
988-
if (ret != 0) {
989-
printf("Failed to start timeout\n");
9901002
goto fail5;
9911003
}
9921004
}
@@ -1035,10 +1047,10 @@ main(int argc, char *argv[])
10351047
}
10361048
#endif
10371049

1038-
#if WASM_ENABLE_THREAD_MGR != 0
1050+
#if WASM_ENABLE_DEBUG_INTERP != 0
10391051
fail5:
10401052
#endif
1041-
#if WASM_ENABLE_DEBUG_INTERP != 0
1053+
#if WASM_ENABLE_THREAD_MGR != 0
10421054
fail4:
10431055
#endif
10441056
/* destroy the module instance */

0 commit comments

Comments
 (0)