Skip to content

Commit 199cb27

Browse files
committed
Start with init:boot/1
Signed-off-by: Paul Guyot <pguyot@kallisys.net>
1 parent 67f0d3f commit 199cb27

File tree

9 files changed

+82
-55
lines changed

9 files changed

+82
-55
lines changed

libs/estdlib/src/init.erl

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,23 @@
2828
-module(init).
2929

3030
-export([
31+
boot/1,
3132
get_argument/1,
3233
get_plain_arguments/0,
3334
notify_when_started/1
3435
]).
3536

37+
%%-----------------------------------------------------------------------------
38+
%% @param Args command line arguments
39+
%% @doc Entry point.
40+
%% @end
41+
%%-----------------------------------------------------------------------------
42+
-spec boot([binary() | atom()]) -> any().
43+
boot([<<"-s">>, StartupModule]) when is_atom(StartupModule) ->
44+
% Until we have boot scripts, we just start kernel application.
45+
{ok, _KernelPid} = kernel:start(boot, []),
46+
StartupModule:start().
47+
3648
%%-----------------------------------------------------------------------------
3749
%% @param Flag flag to get values for
3850
%% @return `error' if no value is associated with provided flag or values in

src/libAtomVM/defaultatoms.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,3 +188,5 @@ X(BREAK_IGNORED_ATOM, "\xD", "break_ignored")
188188

189189
X(SCOPE_ATOM, "\x5", "scope")
190190
X(NOMATCH_ATOM, "\x7", "nomatch")
191+
192+
X(INIT_ATOM, "\x4", "init")

src/libAtomVM/globalcontext.c

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -719,3 +719,40 @@ Module *globalcontext_get_module_by_index(GlobalContext *global, int index)
719719
SMP_RWLOCK_UNLOCK(global->modules_lock);
720720
return result;
721721
}
722+
723+
enum RunResult globalcontext_run(GlobalContext *glb, Module *startup_module)
724+
{
725+
Context *ctx = context_new(glb);
726+
ctx->leader = 1;
727+
Module *init_module = globalcontext_get_module(glb, INIT_ATOM_INDEX);
728+
if (IS_NULL_PTR(init_module)) {
729+
context_execute_loop(ctx, startup_module, "start", 0);
730+
} else {
731+
if (UNLIKELY(memory_ensure_free(ctx, term_binary_heap_size(2) + LIST_SIZE(2, 0)) != MEMORY_GC_OK)) {
732+
fprintf(stderr, "Unable to allocate arguments.\n");
733+
return RUN_MEMORY_FAILURE;
734+
}
735+
term s_opt = term_from_literal_binary("-s", 2, &ctx->heap, glb);
736+
term list = term_list_prepend(module_get_name(startup_module), term_nil(), &ctx->heap);
737+
ctx->x[0] = term_list_prepend(s_opt, list, &ctx->heap);
738+
739+
context_execute_loop(ctx, init_module, "boot", 1);
740+
}
741+
742+
term ret_value = ctx->x[0];
743+
fprintf(stderr, "Return value: ");
744+
term_display(stderr, ret_value, ctx);
745+
fprintf(stderr, "\n");
746+
747+
enum RunResult result;
748+
// ok or 0. 0 is required for running tests for emscripten
749+
if (ret_value == OK_ATOM || ret_value == term_from_int(0)) {
750+
result = RUN_SUCCESS;
751+
} else {
752+
result = RUN_RESULT_NOT_OK;
753+
}
754+
755+
context_destroy(ctx);
756+
757+
return result;
758+
}

src/libAtomVM/globalcontext.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,13 @@ struct RefcBinaryQueueItem
9090
struct RefcBinary *refc;
9191
};
9292

93+
enum RunResult
94+
{
95+
RUN_SUCCESS = 0,
96+
RUN_MEMORY_FAILURE = 1,
97+
RUN_RESULT_NOT_OK = 2,
98+
};
99+
93100
struct GlobalContext
94101
{
95102
struct ListHead ready_processes;
@@ -512,6 +519,20 @@ Module *globalcontext_get_module(GlobalContext *global, atom_index_t module_name
512519
*/
513520
Module *globalcontext_load_module_from_avm(GlobalContext *global, const char *module_name);
514521

522+
/**
523+
* @brief Run a given start module.
524+
*
525+
* @details This function will create a new context and call init:boot/1
526+
* to execute the passed start module. If init module is not found, it will
527+
* fallback to calling start module:start/0 directly. It will also
528+
* print the result to stdout. It will return RUN_SUCCESS if result is ok,
529+
* an error code otherwise.
530+
* @param global the global context
531+
* @param start_module the start module
532+
* @returns RUN_SUCCESS or an error code
533+
*/
534+
enum RunResult globalcontext_run(GlobalContext *global, Module *start_module);
535+
515536
#ifndef __cplusplus
516537
static inline uint64_t globalcontext_get_ref_ticks(GlobalContext *global)
517538
{

src/platforms/emscripten/src/main.c

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -95,23 +95,16 @@ static int start(void)
9595
fprintf(stderr, "main module not loaded\n");
9696
return EXIT_FAILURE;
9797
}
98-
Context *ctx = context_new(global);
99-
ctx->leader = 1;
100-
context_execute_loop(ctx, main_module, "start", 0);
101-
term ret_value = ctx->x[0];
102-
fprintf(stdout, "Return value: ");
103-
term_display(stdout, ret_value, ctx);
104-
fprintf(stdout, "\n");
98+
99+
enum RunResult result = globalcontext_run(global, main_module);
105100

106101
int status;
107-
if (ret_value == OK_ATOM || ret_value == term_from_int(0)) {
102+
if (ret_value == RUN_SUCCESS) {
108103
status = EXIT_SUCCESS;
109104
} else {
110105
status = EXIT_FAILURE;
111106
}
112107

113-
context_destroy(ctx);
114-
115108
return status;
116109
}
117110

src/platforms/esp32/main/main.c

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -119,26 +119,19 @@ void app_main()
119119
AVM_ABORT();
120120
}
121121
globalcontext_insert_module(glb, mod);
122-
Context *ctx = context_new(glb);
123-
ctx->leader = 1;
124122

125123
ESP_LOGI(TAG, "Starting %s...", startup_module_name);
126124
fprintf(stdout, "---\n");
127125

128-
context_execute_loop(ctx, mod, "start", 0);
129-
term ret_value = ctx->x[0];
130-
131-
fprintf(stdout, "AtomVM finished with return value: ");
132-
term_display(stdout, ret_value, ctx);
133-
fprintf(stdout, "\n");
126+
enum RunResult result = globalcontext_run(glb, mod);
134127

135128
bool reboot_on_not_ok =
136129
#if defined(CONFIG_REBOOT_ON_NOT_OK)
137130
CONFIG_REBOOT_ON_NOT_OK ? true : false;
138131
#else
139132
false;
140133
#endif
141-
if (reboot_on_not_ok && ret_value != OK_ATOM) {
134+
if (reboot_on_not_ok && result != RUN_SUCCESS) {
142135
ESP_LOGE(TAG, "AtomVM application terminated with non-ok return value. Rebooting ...");
143136
esp_restart();
144137
} else {

src/platforms/generic_unix/main.c

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -146,24 +146,15 @@ int main(int argc, char **argv)
146146
return EXIT_FAILURE;
147147
}
148148

149-
Context *ctx = context_new(glb);
150-
ctx->leader = 1;
151-
152-
context_execute_loop(ctx, startup_module, "start", 0);
153-
154-
term ret_value = ctx->x[0];
155-
fprintf(stderr, "Return value: ");
156-
term_display(stderr, ret_value, ctx);
157-
fprintf(stderr, "\n");
149+
enum RunResult result = globalcontext_run(glb, startup_module);
158150

159151
int status;
160-
if (ret_value == OK_ATOM) {
152+
if (result == RUN_SUCCESS) {
161153
status = EXIT_SUCCESS;
162154
} else {
163155
status = EXIT_FAILURE;
164156
}
165157

166-
context_destroy(ctx);
167158
globalcontext_destroy(glb);
168159

169160
return status;

src/platforms/rp2/src/main.c

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -132,19 +132,8 @@ static int app_main()
132132

133133
globalcontext_insert_module(glb, mod);
134134
mod->module_platform_data = NULL;
135-
Context *ctx = context_new(glb);
136-
ctx->leader = 1;
137135

138-
fprintf(stderr, "Starting %s...", startup_module_name);
139-
fprintf(stdout, "---\n");
140-
141-
context_execute_loop(ctx, mod, "start", 0);
142-
term ret_value = ctx->x[0];
143-
144-
fprintf(stdout, "AtomVM finished with return value: ");
145-
term_display(stdout, ret_value, ctx);
146-
fprintf(stdout, "\n");
147-
int result = ret_value != OK_ATOM;
136+
enum RunResult result = globalcontext_run(glb, mod);
148137

149138
context_destroy(ctx);
150139

src/platforms/stm32/src/main.c

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -267,30 +267,19 @@ int main()
267267

268268
Module *mod = module_new_from_iff_binary(glb, startup_beam, startup_beam_size);
269269
globalcontext_insert_module(glb, mod);
270-
Context *ctx = context_new(glb);
271-
ctx->leader = 1;
272270

273271
AVM_LOGI(TAG, "Starting: %s...\n", startup_module_name);
274272
fprintf(stdout, "---\n");
275273

276-
context_execute_loop(ctx, mod, "start", 0);
277-
278-
term ret_value = ctx->x[0];
279-
char *ret_atom_string = interop_atom_to_string(ctx, ret_value);
280-
if (ret_atom_string != NULL) {
281-
AVM_LOGI(TAG, "Exited with return: %s", ret_atom_string);
282-
} else {
283-
AVM_LOGI(TAG, "Exited with return value: %lx", (long) term_to_int32(ret_value));
284-
}
285-
free(ret_atom_string);
274+
enum RunResult result = globalcontext_run(glb, mod);
286275

287276
bool reboot_on_not_ok =
288277
#if defined(CONFIG_REBOOT_ON_NOT_OK)
289278
CONFIG_REBOOT_ON_NOT_OK ? true : false;
290279
#else
291280
false;
292281
#endif
293-
if (reboot_on_not_ok && ret_value != OK_ATOM) {
282+
if (reboot_on_not_ok && result != RUN_SUCCESS) {
294283
AVM_LOGE(TAG, "AtomVM application terminated with non-ok return value. Rebooting ...");
295284
scb_reset_system();
296285
} else {

0 commit comments

Comments
 (0)