summaryrefslogtreecommitdiffhomepage
AgeCommit message (Collapse)Author
2022-09-05Merge pull request #102 from jow-/lib-remove-regex-capture-group-limitsJo-Philipp Wich
lib: remove fixed capture group limit in match() and regex replace()
2022-09-05lib: remove fixed capture group limit in match() and regex replace()Jo-Philipp Wich
Instead of supporting only up to 10 potential regular expression captures, infer the amount of required captures directly from the compiled regexp structure and allocate the match range array dynamically. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2022-08-29lib: extend render() to support function valuesJo-Philipp Wich
Extend the `render()` function to accept a function value as first argument, which allows running arbitrary ucode functions and capturing their output. This is especially useful in conjunction with `loadfile()` or `loadstring()` to dynamically compile templates and rendering their output into a string. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2022-08-29lib: improve getenv() and split() implementationsJo-Philipp Wich
- getenv(): Allow querying the entire environment by omiting variable name - split(): Properly handle null bytes in subject and separator strings Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2022-08-24examples: add module search path initialization and freeingJo-Philipp Wich
Since commit 3c168b5 ("vm, cli: move search path into global config...") it is required to explicitly initialize the module search path in the configuration structure for compile time module imports and run time require operations to work. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2022-08-24ubus: fix GCC strncpy() truncation warningJo-Philipp Wich
When building with gcc-10 and -O2, the following warning in ubus.c is triggered during the compilation: In function ‘uc_ubus_object_register’, inlined from ‘uc_ubus_publish’ at .../ubus.c:1521:10: .../ubus.c:1464:14: error: ‘strncpy’ output truncated before terminating nul copying as many bytes from a string as its length [-Werror=stringop-truncation] 1464 | obj->name = strncpy(onptr, ubus_object_name, namelen); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .../ubus.c: In function ‘uc_ubus_publish’: .../ubus.c:1447:12: note: length computed here 1447 | namelen = strlen(ubus_object_name); | ^~~~~~~~~~~~~~~~~~~~~~~~ cc1: all warnings being treated as errors Solve this issue by using memcpy() instead. We already take care of allocating a zeroed, strlen() + 1 sized destination buffer so loosing the `\0` byte of the source string is perfectly fine. Fixes: #100 Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2022-08-24Merge pull request #101 from jow-/loadfile-supportJo-Philipp Wich
lib: introduce three new functions call(), loadstring() and loadfile()
2022-08-24lib: introduce three new functions call(), loadstring() and loadfile()Jo-Philipp Wich
Introduce new functions dealing with on-the-fly compilation of code and execution of functions with different global scope. The `loadstring()` and `loadfile()` functions will compile the given ucode source string or ucode file path respectively and return the entry function of the resulting program. An optional dictionary specifying parse options may be given as second argument. Both functions return `null` on invalid arguments and throw an exception in case of compilation errors. The `call()` function allows invoking a given function value with a different `this` context and/or a different global environment. Finally refactor the existing `uc_require_ucode()` implementation to reuse the new `uc_loadfile()` and `uc_call()` implementations and adjust as well as simplify affected testcases. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2022-08-24lib: introduce helper function for indenting error messagesJo-Philipp Wich
Factor out the nested syntax error message indentation logic into a separate helper procedure for reuse in other places. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2022-08-24lib: simplify include_path()Jo-Philipp Wich
Align the path resolving logic with compiler.c and use strrchr() and a width limited printf pattern to extract the directory name portion. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2022-08-24source: avoid null pointer access in uc_source_runpath_set()Jo-Philipp Wich
When loading a precompiled program from stdin, the input source runpath is unset which subsequently leads to a null pointer being passed to uc_source_runpath_set() when will then attempt to strdup() it, leading to a null pointer access. Properly handle this case and only duplicate non-null pointers. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2022-08-24types: gracefully handle unpatched upvalues in ucv_free()Jo-Philipp Wich
When a module function with unpatched upvalues is freed, ucv_free() might access a NULL pointer through ucv_put_value(), so make sure to skip those unset upvalue slots when freeing a closure. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2022-08-24README.md: document gc() functionJo-Philipp Wich
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2022-08-12Merge pull request #99 from jow-/gc-controlJo-Philipp Wich
Implement periodic GC
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-12lib: implement gc()Jo-Philipp Wich
Introduce a new stdlib function `gc()` which allows controlling the periodic garbage collector from ucode. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2022-08-12vm: support automatic periodic GC runsJo-Philipp Wich
Introduce two new VM api functions uc_vm_gc_start() and uc_vm_gc_stop() which allow starting and stopping automatic periodic garbage collection of cyclic objects in the VM context. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2022-08-12types: treat vm->exports as GC rootsJo-Philipp Wich
We must not free objects being in the module export registry. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2022-08-07Merge pull request #98 from jow-/dynlink-supportJo-Philipp Wich
Add import statement support for dynamic extensions
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-08-06vm: introduce new I_DYNLOAD opcodeJo-Philipp Wich
The I_DYNLOAD opcode is basically a bytecode level instruction for uc_require() with semantics similar to I_IMPORT. It allows loading a dynamic extension library at runtime and treating values from the resulting module context object like exports from a compile time source module. For example the statement `import { readfile, writefile } from "fs"` would import the readfile() and writefile() functions of fs.so as readonly live bindings into the current file scope. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2022-08-06lib: internally expose new uc_require_library() helperJo-Philipp Wich
Break out the core logic of the uc_require() stl function into a new uc_require_library() helper function and make it available for usage outside of lib.c. Also add a new boolean parameter to the helper function which allows restricting runtime require operations of modules to dynamic libraries only. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2022-08-06vm: don't treat offset 0 special for exceptionsJo-Philipp Wich
Try to resolve the source offset to line and character position and only fall back to report the location as instruction offset if we weren't able to determine the line number. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2022-08-06compiler: don't treat offset 0 special at syntax errorsJo-Philipp Wich
If a compile error is raised at offset 0, try to resolve line and character position anyway. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2022-08-06Merge pull request #97 from jow-/module-import-export-fixesJo-Philipp Wich
2022-08-05compiler: improve formatting of nested syntax error messagesJo-Philipp Wich
Indent inner messages and prepend them with a vertical bar to increase visual separation of messages. Also include file name in source context output when the compiled program contains more than one source file. Adjust affected testcase outputs accordingly. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2022-08-05program: remove now unused uc_program_export_lookup()Jo-Philipp Wich
Since we track the offsets in the compiler directly now there's no need to keep this function. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2022-08-05compiler: rework export index allocationJo-Philipp Wich
The current implementation of the module export offset tracking was inadequate and failed to properly handle larger module dependency graphs. In order to properly support nested module imports/exports, the following changes have been introduced: - Gather export slots during module compilation and emit corresponding export opcodes as one contiguous block at the end of the module function body, right before the final return. This ensures that interleaved imports of other modules do not place foreign exports between our module exports. - Track the number of program wide allocated export slots in order to derive per-module-source offsets for the global VM export list. - Derive import opcode source index from the module source export offset and the index of the requested name within the module source export name list. - Improve error reporting for circular module imports. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2022-08-05compiler: fix deriving module path from source runpathJo-Philipp Wich
The current implementation of `uc_compiler_canonicalize_path()` used the entire runtime path of the source object as path prefix, not just the directory part of it. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2022-08-05compiler: enforce stricter module compilation rulesJo-Philipp Wich
- Disallow toplevel `return` statements in module functions - Disallow `export` statements in non-module functions Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2022-08-05vm: don't initialize upvalues for module functionsJo-Philipp Wich
Module function upvalues are patched through import operations, ensure to leave them uninitialized when loading and executing the module constructor. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2022-08-05program: add serialization and deserialization for module function flagJo-Philipp Wich
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2022-08-05compiler: add a flag denoting module functionsJo-Philipp Wich
Introduce a further uc_function_t structure member indicating whether the underlying function is a module constructor. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2022-07-30Merge pull request #96 from jow-/module-import-export-supportJo-Philipp Wich
Module import export support
2022-07-30treewide: unexport libucode internal functionsJo-Philipp Wich
Trim down the libucode.so size somewhat by marking purely internal, non-public API functions hidden. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2022-07-30compiler: add support for import/export statementsJo-Philipp Wich
This commit introduces syntax level support for ES6 style module import and export statements. Imports are resolved at compile time and the corresponding module code is compiled into the main program. Also add testcases to cover import and export statement semantics. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2022-07-30compiler: resolve predeclared upvaluesJo-Philipp Wich
Do not require a parent function compiler reference to lookup an already declared (potentially unresolved) upvalue in the current scope. Instead, search the named upvalues in the current function scope in case there is no parent compiler reference. This is required for the upcoming module support which will use unresolved upvalues to realize import/export functionality. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2022-07-30compiler: require a name in function declarationsJo-Philipp Wich
So far we allowed anonymous toplevel function expressions which makes little sense since those can't be used for anything. Require toplevel function declarations to be named and turn a missing name into a compile time syntax error. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2022-07-30compiler: fix reported source position in inc/dec operator errorJo-Philipp Wich
Report the proper source location when raising an error due to an increment/decrement operation on a constant value. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2022-07-30tests: run_tests.sh: substitute dynamic test directory path in outputJo-Philipp Wich
Replace all occurrences for the test file directory path with "." in stderr and stdout results to ensure stable test outputs. 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-07-30vm: introduce import and export opcodesJo-Philipp Wich
Introduce new opcodes to realize module imports and exports. The export operation will capture a local variable as upvalue and store it in VM wide module export registry while the import operation will connect an upvalue from the module export registry with a preallocated upvalue in the running function scope. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2022-07-30vm: honor constant flag of objects and arraysJo-Philipp Wich
Reject modifications on object and array values with a type exception when the constant flag is set on the value operated upon. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2022-07-30vm: transparently resolve upvalue referencesJo-Philipp Wich
Resolve upvalue references to their actual values when pushing such references onto the stack (or when attempting to call them as method). This allows constructing objects of pointers, as needed for wildcard module imports. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2022-07-30vm: gracefully handle unresolved upvaluesJo-Philipp Wich
Upcoming module support will rely on upresolved upvalues which are patched at runtime to realize module imports, make sure the VM trace code does not choke on such unresolved upvalues. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2022-07-30program: add function to globally lookup exported nameJo-Philipp Wich
Add a helper function to query the global index of a named export within a specific source which is a prerequisite for compiling import statements. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2022-07-30program: add infrastructure to handle multiple sources per programJo-Philipp Wich
The upcoming module support requires maintaining multiple source objects within the same program, so add the necessary infrastructure for it. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2022-07-30program: fix reporting source position of first instructionJo-Philipp Wich
We must always report the chunk source position relative to the function start offset, even if it is zero. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2022-07-30program: fix en/decoding debuginfo upvalue slots in precompiled bytecodeJo-Philipp Wich
The sizeof(size_t) might differ from the sizeof(uint32_t) used to serialize compiled bytecode, so extra care is needed to properly encode and decode upvalue slot values which are defined as (size_t)-1 / 2 + n. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2022-07-30source: add tracking of exported symbolsJo-Philipp Wich
Extend abstract source objects to maintain a list of exported symbols and add functions to append and lookup exported names. Signed-off-by: Jo-Philipp Wich <jo@mein.io>