How to pass arguments to hermes/shermes? #1591
-
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? |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 8 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). |
Beta Was this translation helpful? Give feedback.
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: