Repository navigation
How to pass arguments to hermes/shermes? #1591
Answered
by
tmikov
guest271314
asked this question in
Q&A
|
Typically arguments can be passed to programs in the form For example, when using After compilation to an executable, how do we pass arguments to that program that can be acted on dynamically by the program? |
Answered by
tmikov
Jan 9, 2025
Replies: 1 comment 10 replies
|
We will make this easier, but for now the recommended way to do this is to compile to a named SHUnit and manually link that unit into your own main app. $ shermes -c --exported-unit=hello hello.js
# This produced an object file, hello.o, exporting the unit by name
$ nm hello.o
...
0000000000000000 T _sh_export_hello
...Example main app that filters and saves CLI args: #include "hermes/VM/static_h.h"
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
void init_console_bindings(SHRuntime *shr);
SHUnit *sh_export_hello(void);
static int s_argc;
static char ** s_argv;
// Make the args available to the FFI.
int get_argc(void) { return s_argc; }
char ** get_argv(void) { return s_argv; }
int main(int argc, char **argv) {
// Copy all args up to "--" to pass to the VM.
int vm_argc = 1;
char ** vm_argv = (char **)malloc(sizeof(char *) * argc);
vm_argv[0] = argv[0];
while (vm_argc < argc && strcmp(argv[vm_argc], "--") != 0) {
vm_argv[vm_argc] = argv[vm_argc];
++vm_argc;
}
// Shift the rest as args to pass to the code.
if (vm_argc < argc) {
memmove(argv + 1, argv + vm_argc + 1, sizeof(char *)*(argc - vm_argc - 1));
argc = argc - vm_argc;
} else {
argc = 1;
}
s_argc = argc;
s_argv = argv;
// Debug print the collected args.
#ifndef NDEBUG
printf("vm args:");
for(int i = 0; i < vm_argc; ++i)
printf(" %s", vm_argv[i]);
putchar('\n');
printf("main args:");
for(int i = 0; i < s_argc; ++i)
printf(" %s", s_argv[i]);
putchar('\n');
#endif
SHRuntime *shr = _sh_init(vm_argc, vm_argv);
init_console_bindings(shr);
bool success = _sh_initialize_units(shr, 1, sh_export_hello);
_sh_done(shr);
return success ? 0 : 1;
}# Compile main.c
cc main.c -c -O3 \
-I{$HermesBuildPath?}/lib/config -I{$HermesSourcePath?}/include \
-fno-strict-aliasing -fno-strict-overflow
# Link executable
c++ main.o hello.o -o hello
-L{$HermesBuildPath?}/lib -L{$HermesBuildPath?}/jsi -L{$HermesBuildPath?}/tools/shermes \
-lshermes_console -lhermesvm \
-Wl,-rpath {$HermesBuildPath?}/lib \
-Wl,-rpath {$HermesBuildPath?}/jsi \
-Wl,-rpath {$HermesBuildPath?}/tools/shermes
# Run executable
./hello --gc-max-heap=100M -- 42
vm args: ./hello --gc-max-heap=100M
main args: ./hello 42 (The exact paths and flags may have to be tweaked depending on the use case, for example Wasm, etc). |
10 replies
Answer selected by
tmikov
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
We will make this easier, but for now the recommended way to do this is to compile to a named SHUnit and manually link that unit into your own main app.
$ shermes -c --exported-unit=hello hello.js # This produced an object file, hello.o, exporting the unit by name $ nm hello.o ... 0000000000000000 T _sh_export_hello ...Example main app that filters and saves CLI args: