|
29 | 29 | #include "context.h" |
30 | 30 | #include "defaultatoms.h" |
31 | 31 | #include "erl_nif_priv.h" |
| 32 | +#include "interop.h" |
32 | 33 | #include "list.h" |
33 | 34 | #include "mailbox.h" |
34 | 35 | #include "posix_nifs.h" |
@@ -720,21 +721,62 @@ Module *globalcontext_get_module_by_index(GlobalContext *global, int index) |
720 | 721 | return result; |
721 | 722 | } |
722 | 723 |
|
723 | | -run_result_t globalcontext_run(GlobalContext *glb, Module *startup_module, FILE *out_f) |
| 724 | +run_result_t globalcontext_run(GlobalContext *glb, Module *startup_module, FILE *out_f, int argc, char **argv) |
724 | 725 | { |
725 | 726 | Context *ctx = context_new(glb); |
726 | 727 | ctx->leader = 1; |
727 | 728 | Module *init_module = globalcontext_get_module(glb, INIT_ATOM_INDEX); |
728 | 729 | if (IS_NULL_PTR(init_module)) { |
| 730 | + if (IS_NULL_PTR(startup_module)) { |
| 731 | + fprintf(stderr, "Unable to locate entrypoint.\n"); |
| 732 | + return RUN_NO_ENTRY_POINT; |
| 733 | + } |
729 | 734 | context_execute_loop(ctx, startup_module, "start", 0); |
730 | 735 | } 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; |
| 736 | + // Build boot arguments based on whether we're in embedded mode |
| 737 | + if (argc > 0 && argv != NULL) { |
| 738 | + // Embedded mode: ["-s", escript, "--" | argv_strings] |
| 739 | + // Calculate heap size needed |
| 740 | + size_t heap_needed = term_binary_heap_size(2) + // "-s" |
| 741 | + term_binary_heap_size(2) + // "--" |
| 742 | + LIST_SIZE(3, 0); // list for ["-s", escript, "--"] |
| 743 | + |
| 744 | + // Calculate space for argv strings |
| 745 | + for (int i = 0; i < argc; i++) { |
| 746 | + size_t arg_len = strlen(argv[i]); |
| 747 | + heap_needed += CONS_SIZE * arg_len + LIST_SIZE(1, 0); |
| 748 | + } |
| 749 | + |
| 750 | + if (UNLIKELY(memory_ensure_free(ctx, heap_needed) != MEMORY_GC_OK)) { |
| 751 | + fprintf(stderr, "Unable to allocate arguments.\n"); |
| 752 | + return RUN_MEMORY_FAILURE; |
| 753 | + } |
| 754 | + |
| 755 | + // Build the argv list in reverse: [argvn, ..., argv0, "--", escript, "-s"] |
| 756 | + term args_list = term_nil(); |
| 757 | + for (int i = argc - 1; i >= 0; i--) { |
| 758 | + term arg = interop_chars_to_list(argv[i], strlen(argv[i]), &ctx->heap); |
| 759 | + args_list = term_list_prepend(arg, args_list, &ctx->heap); |
| 760 | + } |
| 761 | + |
| 762 | + term separator = term_from_literal_binary("--", strlen("--"), &ctx->heap, glb); |
| 763 | + args_list = term_list_prepend(separator, args_list, &ctx->heap); |
| 764 | + |
| 765 | + term escript_atom = globalcontext_make_atom(glb, ATOM_STR("\x7", "escript")); |
| 766 | + args_list = term_list_prepend(escript_atom, args_list, &ctx->heap); |
| 767 | + |
| 768 | + term s_opt = term_from_literal_binary("-s", strlen("-s"), &ctx->heap, glb); |
| 769 | + ctx->x[0] = term_list_prepend(s_opt, args_list, &ctx->heap); |
| 770 | + } else { |
| 771 | + // Non-embedded mode: ["-s", startup_module] |
| 772 | + if (UNLIKELY(memory_ensure_free(ctx, term_binary_heap_size(2) + LIST_SIZE(2, 0)) != MEMORY_GC_OK)) { |
| 773 | + fprintf(stderr, "Unable to allocate arguments.\n"); |
| 774 | + return RUN_MEMORY_FAILURE; |
| 775 | + } |
| 776 | + term s_opt = term_from_literal_binary("-s", strlen("-s"), &ctx->heap, glb); |
| 777 | + term list = term_list_prepend(module_get_name(startup_module), term_nil(), &ctx->heap); |
| 778 | + ctx->x[0] = term_list_prepend(s_opt, list, &ctx->heap); |
734 | 779 | } |
735 | | - term s_opt = term_from_literal_binary("-s", strlen("-s"), &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 | 780 |
|
739 | 781 | context_execute_loop(ctx, init_module, "boot", 1); |
740 | 782 | } |
|
0 commit comments