MIRROR: javascript for 馃悳's, a tiny runtime with big ambitions
1#include <compat.h> // IWYU pragma: keep
2
3#include <stdio.h>
4#include <stdlib.h>
5#include <string.h>
6#include <unistd.h>
7#include <sys/stat.h>
8#include <argtable3.h>
9#include <crprintf.h>
10
11#include "ant.h"
12#include "gc.h"
13#include "crash.h"
14#include "repl.h"
15#include "debug.h"
16#include "utils.h"
17#include "watch.h"
18#include "reactor.h"
19#include "runtime.h"
20#include "snapshot.h"
21#include "esm/loader.h"
22#include "esm/library.h"
23#include "esm/remote.h"
24#include "internal.h"
25#include "silver/vm.h"
26#include "messages.h"
27
28#include "cli/pkg.h"
29#include "cli/misc.h"
30#include "cli/version.h"
31
32#include "modules/builtin.h"
33#include "modules/buffer.h"
34#include "modules/atomics.h"
35#include "modules/os.h"
36#include "modules/io.h"
37#include "modules/fs.h"
38#include "modules/crypto.h"
39#include "modules/server.h"
40#include "modules/timer.h"
41#include "modules/json.h"
42#include "modules/fetch.h"
43#include "modules/request.h"
44#include "modules/response.h"
45#include "modules/shell.h"
46#include "modules/process.h"
47#include "modules/tty.h"
48#include "modules/path.h"
49#include "modules/ffi.h"
50#include "modules/events.h"
51#include "modules/lmdb.h"
52#include "modules/performance.h"
53#include "modules/uri.h"
54#include "modules/url.h"
55#include "modules/reflect.h"
56#include "modules/symbol.h"
57#include "modules/date.h"
58#include "modules/math.h"
59#include "modules/bigint.h"
60#include "modules/regex.h"
61#include "modules/textcodec.h"
62#include "modules/sessionstorage.h"
63#include "modules/localstorage.h"
64#include "modules/navigator.h"
65#include "modules/child_process.h"
66#include "modules/readline.h"
67#include "modules/observable.h"
68#include "modules/collections.h"
69#include "modules/iterator.h"
70#include "modules/generator.h"
71#include "modules/module.h"
72#include "modules/util.h"
73#include "modules/async_hooks.h"
74#include "modules/net.h"
75#include "modules/tls.h"
76#include "modules/http_metadata.h"
77#include "modules/http_parser.h"
78#include "modules/http_writer.h"
79#include "modules/dns.h"
80#include "modules/assert.h"
81#include "modules/domexception.h"
82#include "modules/abort.h"
83#include "modules/globals.h"
84#include "modules/intl.h"
85#include "modules/wasm.h"
86#include "modules/string_decoder.h"
87#include "modules/stream.h"
88#include "modules/structured-clone.h"
89#include "modules/v8.h"
90#include "modules/worker_threads.h"
91#include "modules/headers.h"
92#include "modules/blob.h"
93#include "modules/formdata.h"
94#include "modules/zlib.h"
95#include "streams/queuing.h"
96#include "streams/readable.h"
97#include "streams/writable.h"
98#include "streams/transform.h"
99#include "streams/codec.h"
100#include "streams/compression.h"
101
102int js_result = EXIT_SUCCESS;
103typedef int (*cmd_fn)(int argc, char **argv);
104
105typedef struct {
106 const char *name;
107 const char *alias;
108 const char *desc;
109 cmd_fn fn;
110} subcommand_t;
111
112static const subcommand_t subcommands[] = {
113 {"init", NULL, "Create a new package.json", pkg_cmd_init},
114 {"install", "i", "Install dependencies from lockfile", pkg_cmd_install},
115 {"update", "up", "Re-resolve dependencies and refresh lockfile", pkg_cmd_update},
116 {"add", "a", "Add a package to dependencies", pkg_cmd_add},
117 {"remove", "rm", "Remove a package from dependencies", pkg_cmd_remove},
118 {"trust", NULL, "Run lifecycle scripts for packages", pkg_cmd_trust},
119 {"run", NULL, "Run a script from package.json", pkg_cmd_run},
120 {"exec", "x", "Run a command from node_modules/.bin", pkg_cmd_exec},
121 {"why", "explain", "Show why a package is installed", pkg_cmd_why},
122 {"info", NULL, "Show package information from registry", pkg_cmd_info},
123 {"ls", "list", "List installed packages", pkg_cmd_ls},
124 {"cache", NULL, "Manage the package cache", pkg_cmd_cache},
125 {"create", NULL, "Scaffold a project from a template", pkg_cmd_create},
126 {NULL, NULL, NULL, NULL}
127};
128
129static void ant_debug_apply(const char *key, const char *val) {
130 if (strcmp(key, "gc") == 0) {
131 if (strcmp(val, "disable") == 0) gc_disabled = true;
132 }
133
134 else if (strcmp(key, "dump/parse") == 0) {
135 if (strcmp(val, "trace") == 0) sv_debug_enable(SV_DEBUG_PARSE);
136 }
137
138 else if (strcmp(key, "dump/compile") == 0) {
139 if (strcmp(val, "trace") == 0) sv_debug_enable(SV_DEBUG_COMPILE);
140 }
141
142 else if (strcmp(key, "dump/crprintf") == 0) {
143 if (strcmp(val, "bytecode") == 0 || strcmp(val, "all") == 0) crprintf_set_debug(true);
144 if (strcmp(val, "hex") == 0 || strcmp(val, "all") == 0) crprintf_set_debug_hex(true);
145 }
146
147 else if (strcmp(key, "dump/vm") == 0) {
148 if (strcmp(val, "bytecode") == 0 || strcmp(val, "all") == 0) sv_debug_enable(SV_DEBUG_DUMP_BYTECODE);
149 if (strcmp(val, "jit") == 0 || strcmp(val, "all") == 0) sv_debug_enable(SV_DEBUG_DUMP_JIT);
150 if (strcmp(val, "op-warn") == 0 || strcmp(val, "all") == 0) sv_debug_enable(SV_DEBUG_JIT_WARN);
151 }
152}
153
154static inline void setup_console_colors(void) {
155 crprintf_var("version", ANT_VERSION);
156 crprintf_var("fatal", "<bold+red>FATAL</bold>");
157 crprintf_var("error", "<red>Error</red>");
158 crprintf_var("warn", "<yellow>Warning</yellow>");
159}
160
161static void parse_ant_debug_flags(void) {
162 const char *env = getenv("ANT_DEBUG");
163 if (!env || !*env) return;
164
165 char *buf = strdup(env);
166 if (!buf) return;
167
168 char *sp = NULL, *vp = NULL;
169 for (char *e = strtok_r(buf, " ", &sp); e; e = strtok_r(NULL, " ", &sp)) {
170 char *sep = strchr(e, ':');
171 if (!sep) { crfprintf(stderr, msg.unknown_flag_warn, e); continue; }
172 *sep++ = '\0';
173 for (char *v = strtok_r(sep, ",", &vp); v; v = strtok_r(NULL, ",", &vp))
174 ant_debug_apply(e, v);
175 }
176
177 free(buf);
178}
179
180static const subcommand_t *find_subcommand(const char *name) {
181 for (const subcommand_t *cmd = subcommands; cmd->name; cmd++) {
182 if (strcmp(name, cmd->name) == 0) return cmd;
183 if (cmd->alias && strcmp(name, cmd->alias) == 0) return cmd;
184 }
185 return NULL;
186}
187
188static void print_subcommands(void) {
189 crprintf("<bold>Commands:</>\n");
190 for (const subcommand_t *cmd = subcommands; cmd->name; cmd++) {
191 crprintf(" <pad=18>%s</pad> %s\n", cmd->name, cmd->desc);
192 }
193 crprintf(msg.ant_command_extra);
194 printf("\n");
195}
196
197static void print_commands(void **argtable) {
198 crprintf(msg.ant_help_header);
199
200 print_subcommands();
201 crprintf(msg.ant_help_flags);
202
203 print_flags_help(stdout, argtable);
204 print_flag(stdout, (flag_help_t){ .l = "verbose", .g = "enable verbose output" });
205 print_flag(stdout, (flag_help_t){ .l = "no-color", .g = "disable colored output" });
206}
207
208typedef struct {
209 int argc;
210 char **argv;
211} argv_split_t;
212
213static bool is_valued_flag(const char *arg) {
214 return
215 strcmp(arg, "-e") == 0 ||
216 strcmp(arg, "--eval") == 0 ||
217 strcmp(arg, "--localstorage-file") == 0;
218}
219
220static int find_argv_token_index(int argc, char **argv, const char *token) {
221 if (!token) return -1;
222 for (int i = 1; i < argc; i++) if (argv[i] == token) return i;
223 return -1;
224}
225
226static argv_split_t split_script_args(int *argc, char **argv) {
227 for (int i = 1; i < *argc; i++) {
228 if (strcmp(argv[i], "--") == 0) {
229 argv_split_t tail = { *argc - i - 1, argv + i + 1 };
230 *argc = i;
231 return tail;
232 }
233
234 if (argv[i][0] == '-') {
235 if (is_valued_flag(argv[i]) && i + 1 < *argc) i++;
236 continue;
237 }
238
239 argv_split_t tail = { *argc - i - 1, argv + i + 1 };
240 *argc = i + 1;
241 return tail;
242 }
243
244 return (argv_split_t){ 0, NULL };
245}
246
247static argv_split_t build_process_argv(int argc, char **argv, const char *module, argv_split_t script) {
248 if (!module || script.argc == 0) return (argv_split_t){ argc, argv };
249
250 int total = 2 + script.argc;
251 char **out = try_oom(sizeof(char*) * (total + 1));
252
253 out[0] = argv[0]; out[1] = (char *)module;
254 for (int i = 0; i < script.argc; i++) out[2 + i] = script.argv[i];
255 out[total] = NULL;
256
257 return (argv_split_t){ total, out };
258}
259
260static char *read_stdin(size_t *len) {
261 size_t cap = 4096;
262 *len = 0;
263 char *buf = malloc(cap);
264 if (!buf) return NULL;
265
266 size_t n;
267 while ((n = fread(buf + *len, 1, cap - *len, stdin)) > 0) {
268 *len += n;
269 if (*len == cap) {
270 cap *= 2; char *next = realloc(buf, cap);
271 if (!next) { free(buf); return NULL; }
272 buf = next;
273 }
274 }
275 buf[*len] = '\0';
276 return buf;
277}
278
279static char *read_file(const char *filename, size_t *len) {
280 FILE *fp = fopen(filename, "rb");
281 if (!fp) return NULL;
282
283 fseek(fp, 0, SEEK_END);
284 long size = ftell(fp);
285 fseek(fp, 0, SEEK_SET);
286
287 char *buffer = malloc(size + 1);
288 if (!buffer) {
289 fclose(fp);
290 return NULL;
291 }
292
293 *len = fread(buffer, 1, size, fp);
294 fclose(fp);
295 buffer[*len] = '\0';
296
297 return buffer;
298}
299
300static void eval_code(ant_t *js, const char *script, size_t len, const char *tag, bool should_print) {
301 js_set_filename(js, tag);
302 js_setup_import_meta(js, tag);
303
304 js_set(js, js_glob(js), "__dirname", js_mkstr(js, ".", 1));
305 js_set(js, js_glob(js), "__filename", js_mkstr(js, tag, strlen(tag)));
306
307 ant_value_t result = js_eval_bytecode_eval(js, script, len);
308 js_run_event_loop(js);
309
310 if (print_uncaught_throw(js)) {
311 js_result = EXIT_FAILURE;
312 return;
313 }
314
315 char cbuf_stack[512]; js_cstr_t cstr = js_to_cstr(
316 js, result, cbuf_stack, sizeof(cbuf_stack)
317 );
318
319 if (vtype(result) == T_ERR) {
320 fprintf(stderr, "%s\n", cstr.ptr);
321 js_result = EXIT_FAILURE;
322 } else if (should_print) {
323 if (vtype(result) == T_STR) printf("%s\n", cstr.ptr ? cstr.ptr : "");
324 else if (cstr.ptr && strcmp(cstr.ptr, "undefined") != 0) {
325 print_value_colored(cstr.ptr, stdout); printf("\n");
326 }
327 }
328
329 if (cstr.needs_free) free((void *)cstr.ptr);
330}
331
332static int execute_module(ant_t *js, const char *filename) {
333 char *use_path_owned = NULL;
334
335 const char *use_path = filename;
336 const char *stable_use_path = filename;
337
338 ant_value_t ns = 0;
339 ant_value_t specifier = 0;
340 ant_value_t default_export = 0;
341
342 if (esm_is_url(filename)) {
343 js_set(js, js_glob(js), "__dirname", js_mkundef());
344 specifier = js_mkstr(js, filename, strlen(filename));
345 } else {
346 char *file_path = strdup(filename);
347 char *dir = dirname(file_path);
348 js_set(js, js_glob(js), "__dirname", js_mkstr(js, dir, strlen(dir)));
349 free(file_path);
350
351 use_path_owned = realpath(filename, NULL);
352 if (use_path_owned) use_path = use_path_owned;
353 specifier = js_esm_make_file_url(js, use_path);
354 }
355
356 const char *interned = intern_string(use_path, strlen(use_path));
357 if (interned) stable_use_path = interned;
358 else stable_use_path = use_path;
359
360 js_set(js, js_glob(js),
361 "__filename",
362 js_mkstr(js, filename, strlen(filename))
363 );
364
365 js_set_filename(js, stable_use_path);
366 js_setup_import_meta(js, stable_use_path);
367 ns = js_esm_import_sync(js, specifier);
368
369 free(use_path_owned);
370 if (print_uncaught_throw(js)) return EXIT_FAILURE;
371
372 if (vtype(ns) == T_ERR) {
373 fprintf(stderr, "%s\n", js_str(js, ns));
374 return EXIT_FAILURE;
375 }
376
377 default_export = js_get(js, ns, "default");
378 return server_maybe_start_from_export(js, default_export);
379}
380
381int main(int argc, char *argv[]) {
382 bool internal_crash_report_mode = ant_crash_is_internal_report(argc, argv);
383
384 if (internal_crash_report_mode) argc = 1;
385 if (!internal_crash_report_mode && !getenv("ANT_NO_CRASH_HANDLER")) ant_crash_init(argc, argv);
386
387 setup_console_colors();
388 parse_ant_debug_flags();
389
390 int filtered_argc = 0; int original_argc = argc;
391 char **original_argv = argv;
392
393 const char *binary_name = strrchr(argv[0], '/');
394 binary_name = binary_name ? binary_name + 1 : argv[0];
395
396 if (strcmp(binary_name, "antx") == 0) {
397 char **exec_argv = try_oom(sizeof(char*) * (argc + 2));
398 exec_argv[0] = argv[0]; exec_argv[1] = "x";
399
400 for (int i = 1; i < argc; i++) exec_argv[i + 1] = argv[i];
401 exec_argv[argc + 1] = NULL;
402
403 int exitcode = pkg_cmd_exec(argc, exec_argv + 1);
404 free(exec_argv); return exitcode;
405 }
406
407 char **filtered_argv = try_oom(sizeof(char*) * argc);
408 for (int i = 0; i < argc; i++) {
409 if (strcmp(argv[i], "--verbose") == 0) pkg_verbose = true;
410 else if (strcmp(argv[i], "--no-color") == 0) { crprintf_set_color(false); io_no_color = true; }
411 else if (strncmp(argv[i], "--stack-size=", 13) == 0) sv_user_stack_size_kb = atoi(argv[i] + 13);
412 else filtered_argv[filtered_argc++] = argv[i];
413 }
414
415 argc = filtered_argc;
416 argv = filtered_argv;
417
418 argv_split_t script_tail = split_script_args(&argc, argv);
419 argv_split_t proc_argv = { 0, NULL };
420
421 #define ARG_ITEMS(X) \
422 X(struct arg_str *, eval, arg_str0("e", "eval", "<script>", "evaluate script")) \
423 X(struct arg_lit *, print, arg_lit0("p", "print", "evaluate script and print result")) \
424 X(struct arg_lit *, watch, arg_lit0("w", "watch", "restart process when entry file changes")) \
425 X(struct arg_lit *, no_clear_screen, arg_lit0(NULL, "no-clear-screen", "keep output when restarting in watch mode")) \
426 X(struct arg_file *, localstorage_file, arg_file0(NULL, "localstorage-file", "<path>", "file path for localStorage persistence")) \
427 X(struct arg_file *, file, arg_filen(NULL, NULL, NULL, 0, argc, NULL)) \
428 X(struct arg_lit *, version, arg_lit0("v", "version", "display version information and exit")) \
429 X(struct arg_lit *, version_raw, arg_lit0(NULL, "version-raw", "raw version number for scripts")) \
430 X(struct arg_lit *, help, arg_lit0("h", "help", "display this help and exit")) \
431 X(struct arg_end *, end, arg_end(20))
432
433 #define DECL(t, n, init) t n = init;
434 ARG_ITEMS(DECL)
435 #undef DECL
436
437 #define REF(t, n, init) n,
438 void *argtable[] = { ARG_ITEMS(REF) };
439 int nerrors = arg_parse(argc, argv, argtable);
440 #undef REF
441
442 #define CLEANUP_ARGS_AND_ARGV() ({ \
443 if (proc_argv.argv != argv) free(proc_argv.argv); \
444 arg_freetable(argtable, ARGTABLE_COUNT); \
445 free(filtered_argv); \
446 })
447
448 if (help->count > 0) {
449 print_commands(argtable);
450 CLEANUP_ARGS_AND_ARGV();
451 return EXIT_SUCCESS;
452 }
453
454 if (version_raw->count > 0) {
455 fputs(ANT_VERSION "\n", stdout);
456 CLEANUP_ARGS_AND_ARGV();
457 return EXIT_SUCCESS;
458 }
459
460 if (version->count > 0) {
461 int res = ant_version(argtable);
462 free(filtered_argv); return res;
463 }
464
465
466 if (nerrors > 0) {
467 print_errors(stdout, end);
468 print_commands(argtable);
469 CLEANUP_ARGS_AND_ARGV();
470 return EXIT_FAILURE;
471 }
472
473 if (no_clear_screen->count > 0 && watch->count == 0) {
474 crfprintf(stderr, msg.misuse_clear_screen);
475 CLEANUP_ARGS_AND_ARGV();
476 return EXIT_FAILURE;
477 }
478
479 if (eval->count == 0 && file->count > 0 && file->filename[0] != NULL) {
480 const char *positional = file->filename[0];
481 int first_pos_idx = find_argv_token_index(argc, argv, positional);
482
483 if (first_pos_idx <= 0 || first_pos_idx >= argc) {
484 crfprintf(stderr, msg.argument_fatal);
485 CLEANUP_ARGS_AND_ARGV();
486 return EXIT_FAILURE;
487 }
488
489 const subcommand_t *cmd = find_subcommand(positional);
490
491 if (cmd) {
492 if (watch->count > 0) {
493 crfprintf(stderr, msg.watch_subcommand_error);
494 CLEANUP_ARGS_AND_ARGV();
495 return EXIT_FAILURE;
496 }
497
498 int cmd_argc = argc - first_pos_idx;
499 char **cmd_argv = argv + first_pos_idx;
500 char **cmd_argv_full = NULL;
501
502 if (script_tail.argc > 0) {
503 cmd_argv_full = try_oom(sizeof(*cmd_argv_full) * (size_t)(cmd_argc + script_tail.argc + 1));
504
505 memcpy(cmd_argv_full, cmd_argv, sizeof(*cmd_argv_full) * (size_t)cmd_argc);
506 memcpy(cmd_argv_full + cmd_argc, script_tail.argv, sizeof(*cmd_argv_full) * (size_t)script_tail.argc);
507
508 cmd_argc += script_tail.argc;
509 cmd_argv_full[cmd_argc] = NULL;
510 cmd_argv = cmd_argv_full;
511 }
512
513 int exitcode = cmd->fn(cmd_argc, cmd_argv);
514 free(cmd_argv_full);
515
516 CLEANUP_ARGS_AND_ARGV();
517 return exitcode;
518 }
519
520 if (pkg_script_exists("package.json", positional)) {
521 if (watch->count > 0) {
522 crfprintf(stderr, msg.watch_subcommand_error);
523 CLEANUP_ARGS_AND_ARGV();
524 return EXIT_FAILURE;
525 }
526
527 int run_argc = argc - first_pos_idx + 1 + script_tail.argc;
528 char **run_argv = try_oom(sizeof(*run_argv) * (size_t)(run_argc + 1));
529
530 run_argv[0] = argv[0];
531 int copied = argc - first_pos_idx;
532
533 memcpy(run_argv + 1, argv + first_pos_idx, sizeof(*run_argv) * (size_t)copied);
534 if (script_tail.argc > 0) {
535 memcpy(run_argv + 1 + copied, script_tail.argv, sizeof(*run_argv) * (size_t)script_tail.argc);
536 }
537
538 run_argv[run_argc] = NULL;
539 int exitcode = pkg_cmd_run(run_argc, run_argv);
540
541 free(run_argv);
542 CLEANUP_ARGS_AND_ARGV();
543
544 return exitcode;
545 }
546 }
547
548 bool has_stdin = !isatty(STDIN_FILENO);
549 bool repl_mode = (file->count == 0 && eval->count == 0 && !has_stdin);
550 bool stdin_mode = (has_stdin && file->count == 0);
551
552 if (watch->count > 0 && (eval->count > 0 || repl_mode || stdin_mode)) {
553 crfprintf(stderr, msg.watch_module_error);
554 CLEANUP_ARGS_AND_ARGV();
555 return EXIT_FAILURE;
556 }
557
558 const char *module_file = (repl_mode || file->count == 0)
559 ? NULL
560 : file->filename[0];
561
562 if (watch->count > 0) {
563 char *resolved_file = NULL;
564
565 resolved_file = resolve_js_file(module_file);
566 if (resolved_file) module_file = resolved_file;
567
568 if (!module_file || esm_is_url(module_file)) {
569 crfprintf(stderr, msg.watch_entrypoint_error);
570 if (resolved_file) free(resolved_file);
571 CLEANUP_ARGS_AND_ARGV();
572 return EXIT_FAILURE;
573 }
574
575 int res = ant_watch_run(original_argc, original_argv, module_file, no_clear_screen->count > 0);
576 if (resolved_file) free(resolved_file);
577 CLEANUP_ARGS_AND_ARGV();
578 return res;
579 }
580
581 ant_t *js;
582 volatile char stack_base;
583
584 if (!(js = js_create_dynamic())) {
585 crfprintf(stderr, msg.ant_allocation_fatal);
586 CLEANUP_ARGS_AND_ARGV();
587 return EXIT_FAILURE;
588 }
589
590 js_setstackbase(js, (void *)&stack_base);
591 js_setstacklimit(js, os_thread_stack_size() * 3 / 4);
592
593 proc_argv = build_process_argv(argc, argv, module_file, script_tail);
594 ant_runtime_init(js, proc_argv.argc, proc_argv.argv, localstorage_file);
595
596 init_symbol_module();
597 init_iterator_module();
598 init_generator_module();
599 init_timer_module();
600 init_domexception_module();
601 init_globals_module();
602 init_intl_module();
603 init_wasm_module();
604 init_builtin_module();
605 init_buffer_module();
606 init_structured_clone_module();
607 init_abort_module();
608 init_headers_module();
609 init_blob_module();
610 init_formdata_module();
611 init_math_module();
612 init_bigint_module();
613 init_date_module();
614 init_regex_module();
615 init_collections_module();
616 init_queuing_strategies_module();
617 init_readable_stream_module();
618 init_writable_stream_module();
619 init_transform_stream_module();
620 init_codec_stream_module();
621 init_compression_stream_module();
622 init_fs_module();
623 init_atomics_module();
624 init_crypto_module();
625 init_request_module();
626 init_response_module();
627 init_fetch_module();
628 init_console_module();
629 init_json_module();
630 init_process_module();
631 init_tty_module();
632 init_events_module();
633 init_performance_module();
634 init_uri_module();
635 init_url_module();
636 init_reflect_module();
637 init_textcodec_module();
638 init_sessionstorage_module();
639 init_localstorage_module();
640 init_navigator_module();
641 init_observable_module();
642
643 ant_register_library(shell_library, "ant:shell", NULL);
644 ant_register_library(ffi_library, "ant:ffi", NULL);
645 ant_register_library(lmdb_library, "ant:lmdb", NULL);
646
647 ant_register_library(internal_tls_library, "ant:internal/tls", NULL);
648 ant_register_library(internal_http_parser_library, "ant:internal/http_parser", NULL);
649 ant_register_library(internal_http_writer_library, "ant:internal/http_writer", NULL);
650 ant_register_library(internal_http_metadata_library, "ant:internal/http_metadata", NULL);
651
652 ant_standard_library("util", util_library);
653 ant_standard_library("util/types", util_types_library);
654 ant_standard_library("console", console_library);
655 ant_standard_library("net", net_library);
656 ant_standard_library("dns", dns_library);
657 ant_standard_library("assert", assert_library);
658 ant_standard_library("module", module_library);
659 ant_standard_library("buffer", buffer_library);
660 ant_standard_library("path", path_library);
661 ant_standard_library("fs", fs_library);
662 ant_standard_library("constants", fs_constants_library);
663 ant_standard_library("os", os_library);
664 ant_standard_library("url", url_library);
665 ant_standard_library("perf_hooks", perf_hooks_library);
666 ant_standard_library("process", process_library);
667 ant_standard_library("crypto", crypto_library);
668 ant_standard_library("events", events_library);
669 ant_standard_library("tty", tty_library);
670 ant_standard_library("readline", readline_library);
671 ant_standard_library("child_process", child_process_library);
672 ant_standard_library("worker_threads", worker_threads_library);
673 ant_standard_library("async_hooks", async_hooks_library);
674 ant_standard_library("v8", v8_library);
675 ant_standard_library("zlib", zlib_library);
676 ant_standard_library("string_decoder", string_decoder_library);
677 ant_standard_library("stream", stream_library);
678 ant_standard_library("timers", timers_library);
679
680 ant_register_library(path_posix_library, "path/posix", "ant:path/posix", "node:path/posix", NULL);
681 ant_register_library(path_win32_library, "path/win32", "ant:path/win32", "node:path/win32", NULL);
682
683 ant_standard_library("fs/promises", fs_promises_library);
684 ant_standard_library("timers/promises", timers_promises_library);
685 ant_standard_library("readline/promises", readline_promises_library);
686 ant_standard_library("stream/promises", stream_promises_library);
687 ant_standard_library("stream/web", stream_web_library);
688
689 ant_value_t snapshot_result = ant_load_snapshot(js);
690 if (vtype(snapshot_result) == T_ERR) {
691 crfprintf(stderr, msg.snapshot_warn, js_str(js, snapshot_result));
692 }
693
694 if (internal_crash_report_mode) {
695 js_result = ant_crash_run_internal_report(js);
696 }
697
698 else if (eval->count > 0) {
699 const char *script = eval->sval[0];
700 eval_code(js, script, strlen(script), "[eval]", print->count > 0);
701 }
702
703 else if (repl_mode) {
704 ant_repl_run();
705 }
706
707 else if (stdin_mode) {
708 size_t len = 0; char *buf = read_stdin(&len);
709 if (!buf) {
710 crfprintf(stderr, msg.ant_allocation_fatal);
711 js_result = EXIT_FAILURE; goto cleanup;
712 }
713 eval_code(js, buf, len, "[stdin]", print->count > 0); free(buf);
714 }
715
716 else {
717 for (int fi = 0; fi < file->count; fi++) {
718 const char *fl = file->filename[fi];
719 char *resolved_file = resolve_js_file(fl);
720 if (!resolved_file) {
721 crfprintf(stderr, msg.module_not_found, fl);
722 js_result = EXIT_FAILURE; break;
723 }
724
725 fl = resolved_file;
726 js_result = execute_module(js, fl);
727 js_run_event_loop(js);
728
729 free(resolved_file);
730 if (js_result != EXIT_SUCCESS) break;
731 }}
732
733 cleanup: {
734 js_destroy(js);
735 CLEANUP_ARGS_AND_ARGV();
736 }
737 #undef CLEANUP_ARGS_AND_ARGV
738
739 return js_result;
740}