summaryrefslogtreecommitdiffhomepage
path: root/main.c
AgeCommit message (Collapse)Author
2024-07-29main: prevent invalid memory access when executing empty stdinJo-Philipp Wich
In case the ucode cli executes stdin with zero bytes length, ensure to pass a dummy string instead of a NULL pointer to uc_source_new_buffer() to prevent libc's fmemopen() from writing to nonexistent memory. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2023-07-27main: enable signal dispatching in the standalone cli interpreterJo-Philipp Wich
Enable signal dispatching by default for standalone ucode programs. Also adjust the `gc()` testcase output as the default number of allocations with enabled signal dispatching changes slightly. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2023-05-27main: add user specified library search paths before default pathFelix Fietkau
Allow -L to add library paths that take precedence over the built-in ones. Signed-off-by: Felix Fietkau <nbd@nbd.name>
2022-10-04main: implement print modeJo-Philipp Wich
Introduce a new `-p` flag which works like `-e` but prints the final expression result. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2022-08-12main: introduce -g flag to allow enabling periodic gc from cliJo-Philipp Wich
Implement a new flag `-g` which takes an interval value and enables the periodic GC with the given interval for cyclic object structures in the VM if specified. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2022-08-06compiler: add import statement support for dynamic extensionsJo-Philipp Wich
Utilize the new I_DYNLINK vm opcode to support import statements referring to dynamic extension modules. During compilation, the compiler will try to infer the type of the imported module from the resolved file path; if it ends with `.so`, the module is assumed to by a dynamic extension and loading/binding of the module is deferred to runtime using I_DYNLINK opcodes. Additionally, the `-c` cli option gained support for a new compiler flag `dynlink=...` which allows forcing a particular module name expression to be treated as dynamic extension. This is useful to e.g. force resolving `import { x } from "foo"` to a dynamic extension `foo.so` loaded at runtime even if a plain `foo.uc` exists in the search path during compilation or if no such module is available at build time. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2022-07-30vm, cli: move search path into global configuration structureJo-Philipp Wich
The upcoming compile-time module support will require the configured extension search path in the compiler as well, so move it to the already shared uc_parse_config_t structure and add the appropriate utility functions to initialize, append and free the search path vector. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2022-04-07treewide: move json-c compat shims into internal header fileJo-Philipp Wich
Do not expose the json-c compat functions in ucode's public headers to avoid clashes when building on systems with modern json-c. Also remove some explicit json-c/json-c.h includes in places where it is not needed. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2022-04-07main: abort when failing to load a preload libraryJo-Philipp Wich
Do not continue loading other libraries or executing the main code if loading one of the preload libraries fails. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2022-03-21main: turn ucode into multicall executableJo-Philipp Wich
Turn the ucode executable into a multicall binary and select default flags based on the name it was invoked with. Introduce two new symlinks "ucc" and "utpl" which start ucode in compile and template mode respectively. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2022-03-15treewide: remove legacy json-c include directivesJo-Philipp Wich
We now include `json-c/json-c.h` on all supported environments. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2022-03-14main: rework CLI frontendJo-Philipp Wich
- Change command line flags to be align better with those of other interpreters and with the gcc compiler, e.g. `-D` and `-U` to define and undefine globals, `-e` to execute script expression etc. - Pass only excess CLI arguments as `ARGV` to scripts, e.g. `ucode -e 'print("Hello world")' -- -x -y` would pass only `[ "-x", "-y" ]` as ARGV contents - Default to raw mode and introduce flag to enable template mode Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2022-02-07treewide: rework function memory modelJo-Philipp Wich
- Instead of treating individual program functions as managed ucode types, demote uc_function_t values to pointers into a uc_program_t entity - Promote uc_program_t to a managed type - Let uc_closure_t claim references to the owning program of the enclosed uc_function_t - Redefine public APIs uc_compile() and uc_vm_execute() APIs to return and expect an uc_program_t object respectively - Remove vallist indirection for function loading and let the compiler emit the function id directly when producing function construction code Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2022-01-29program: rename bytecode load/write functions, track path of executed fileJo-Philipp Wich
Extend source objects with a `runpath` field which contains the original path of the source being executed by the VM. When instantiating source objects from file paths, the `runpath` will be set to the `filename`. When instantiating source buffers using `uc_source_new_buffer()`, the runpath is initially unset. A new function `uc_source_runpath_set()` can be used to adjust the runtime path being associated with a source object. Extend bytecode loading logic to set the source buffer runtime path to the precompiled bytecode file path being loaded and executed. This is required for `sourcepath()` and relative paths in `include()` to function correctly when executing precompiled programs. Finally rename `uc_program_from_file()` and `uc_program_to_file()` to `uc_program_load()` and `uc_program_write()` respectively since the load part now operates on an `uc_source_t` input buffer instead of a plain `FILE *` handle. Adjust users of these API functions accordingly. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2022-01-18program: implement support for precompiling source filesJo-Philipp Wich
- Introduce new command line flags `-o` and `-O` to write compiled program code into the specified output file - Add support for transparently executing precompiled files, the lexical analyzing and com,pilation phase is skipped in this case Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2021-09-21main: fix leaking module name when processing -m flagJo-Philipp Wich
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2021-07-11treewide: harmonize function namingJo-Philipp Wich
- Ensure that most functions follow the subject_verb naming schema - Move type related function from value.c to types.c - Rename value.c to vallist.c Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2021-07-11treewide: move header files into dedicated directoryJo-Philipp Wich
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2021-07-11main: introduce new flag `-x` to allow disabling specific functionsJo-Philipp Wich
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2021-07-11main: refactor option parsing and VM setupJo-Philipp Wich
Set VM options and environment variables and load modules on the fly while parsing the cli options instead of aggregating all the values in memory first. This vastly reduces the amount of arguments we need to pass to the parse() function. Also rename parse() to compile() while we're at it. Also slightly adjust the usage output. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2021-07-11treewide: consolidate typedef namingJo-Philipp Wich
Ensure that all custom typedef and vector declaration type names end with a "_t" suffix. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2021-07-11vm: add API to control trace modeJo-Philipp Wich
Add a public getter and setter to read and set the VM trace level respectively. Use the new API to control the trace mode with a newly introduced `-t` command line switch. Drop support for honouring the `TRACE` environment variable as host programs embedding ucode might want to prevent that behaviour or handle it differently. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2021-07-11lib, vm: reimplement exit() as exception typeJo-Philipp Wich
Instead of invoking exit(3) from uc_exit(), use a new EXCEPTION_EXIT exception type to instruct the VM to shutdown cleanly. This is required to not terminate the host program in case libucode is embedded and loaded scripts invoke the exit() function. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2021-07-11vm: extend API to allow returning result value from VM executionJo-Philipp Wich
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2021-07-11vm: remove module preloading logicJo-Philipp Wich
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2021-07-11main: preload modules ourselvesJo-Philipp Wich
Module preloading is a cli frontend specific feature, it does not belong into the VM API, therfore do the module preloading directly in main.c to allow removing the corresponding VM code in a subsequent commit. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2021-07-11vm: move global scope allocation into uc_vm_init()Jo-Philipp Wich
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2021-05-25lexer: implement raw code modeJo-Philipp Wich
Enabling raw code mode allows writing ucode scripts without any template tag decorations (that is, without the need to provide an initial opening '{%' tag). Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2021-05-25lib: rename uc_lib_init() to uc_load_stdlib()Jo-Philipp Wich
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2021-05-25main, lib: move allocation of globals object into lib functionJo-Philipp Wich
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2021-05-25main: simplify REQUIRE_SEARCH_PATH initializationJo-Philipp Wich
Do not require parsing in C, pre-split string in cmake and pass it as command separated string array down to CPP, so that it can be interpolated directly into a char *path[] array. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2021-05-14lexer: skip interpreter line in any source bufferJo-Philipp Wich
Skip interpreter lines in any source buffer and handle the skipping in the lexer itself, to avoid reporting wrongly shifted token offsets to the compiler, resulting in wrong error locations and source contexts. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2021-05-14main: expose argv as global ARGV array to ucode scriptsJo-Philipp Wich
This allows accessing the arguments of the invoked command line. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2021-04-27treewide: ISO C / pedantic complianceJo-Philipp Wich
- Shuffle typedefs to avoid need for non-compliant forward declarations - Fix non-compliant empty struct initializers - Remove use of braced expressions - Remove use of anonymous unions - Avoid `void *` pointer arithmetic - Fix several warnings reported by gcc -pedantic mode and clang 11 compilation Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2021-04-26main: fix ineffective EOF check in parse()Jo-Philipp Wich
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2021-04-25treewide: rework internal data type systemJo-Philipp Wich
Instead of relying on json_object values internally, use custom types to represent the different ucode value types which brings a number of advantages compared to the previous approach: - Due to the use of tagged pointers, small integer, string and bool values can be stored directly in the pointer addresses, vastly reducing required heap memory - Ability to create circular data structures such as `let o; o = { test: o };` - Ability to register custom `tostring()` function through prototypes - Initial mark/sweep GC implementation to tear down circular object graphs on VM deinit The change also paves the way for possible future extensions such as constant variables and meta methods for custom ressource types. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2021-04-24treewide: fix issues reported by clang code analyzerJo-Philipp Wich
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2021-04-23main: provide just binary name in help outputPetr Štetiar
Otherwise it prints out complete path which is probably not desired and we would need to filter out paths in the test's output etc. Signed-off-by: Petr Štetiar <ynezz@true.cz>
2021-03-08main: expose global prototype as `global` property on root scopeJo-Philipp Wich
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2021-02-17treewide: rewrite ucode interpreterJo-Philipp Wich
Replace the former AST walking interpreter implementation with a single pass bytecode compiler and a corresponding virtual machine. The rewrite lays the groundwork for a couple of improvements with will be subsequently implemented: - Ability to precompile ucode sources into binary byte code - Strippable debug information - Reduced runtime memory usage Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2020-12-06treewide: prevent stale pointer access in opcode handlersJo-Philipp Wich
Instead of obtaining and caching direct opcode pointers, use relative references when dealing with opcodes since direct or indirect calls to uc_execute_op() might lead to reallocations of the opcode array, shifting memory addresses and invalidating pointers taken before the invocation. Such stale pointer accesses could be commonly triggered when one part of the processed expression was a require() or include() call loading relatively large ucode sources. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2020-11-19treewide: rebrand to ucodeJo-Philipp Wich
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2020-11-10main: fix double free when using multiple -E optionsJo-Philipp Wich
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2020-10-31main: allow prefixing -e and -E optionsJo-Philipp Wich
By specifying a name, followed by an equal sign before the actual option value, the corresponding JSON data is stored as global variable with the given name, instead of turning each object key into a variable itself. For example while `utpl -e '{ "foo": true, "bar": false }' ...` will set two variables `foo` and `bar`, the alternative syntax `utpl -e 'baz={ "foo": true, "bar": false }' ...` will declare a single variable `baz` holding the object `{ "foo": true, "bar": false }`. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2020-10-31main: fix leading byte corruption when not starting with #!Jo-Philipp Wich
Reverse the order of the ungetc() calls to properly restore the first two probed bytes. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2020-10-14treewide: unify error handlingJo-Philipp Wich
Get rid of the distinction between lexer/parser errors and runtime exceptions, use exceptions everywhere instead. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2020-10-14treewide: rework source file and callstack handlingJo-Philipp Wich
- Keep an open FILE* reference to processed source files in order to be able to rewind and extract error context later - Build a proper call stack when invoking utpl functions - Report call stack in exceptions Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2020-10-14lexer: rewriteJo-Philipp Wich
Rewrite the lexer into a restartable state machine to support parsing from file streams without the need to read the entire source text into memory first. As a side effect, the length of labels and strings is unlimited now. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2020-10-02lib: tweak error context formattingJo-Philipp Wich
Do not emit additional newline when formatting error context and print it instead when outputting the exception. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2020-10-02treewide: rework handling of memory allocation failuresJo-Philipp Wich
Instead of propagating failures to the caller, print a generic error message and terminate program execution through abort(). Signed-off-by: Jo-Philipp Wich <jo@mein.io>