summaryrefslogtreecommitdiffhomepage
path: root/include
AgeCommit message (Collapse)Author
2024-02-21vm: rework object iterationJo-Philipp Wich
Ensure that deleting object keys during iteration is safe by keeping a global chain of per-object iterators which are advanced to the next key when the entry that is about to be iterated is deleted. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2023-11-06syntax: don't treat `as` and `from` as reserved keywordsJo-Philipp Wich
ECMAScript allows using `as` and `from` as identifiers so follow suit and don't treat them specially while parsing. Extend the compiler logic instead to check for TK_LABEL tokens with the expected value to properly parse import and export statements. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2023-10-09include: fix execvpe compat function on macOSFelix Fietkau
Accept char * const *, cast internally. Fixes a compile error Signed-off-by: Felix Fietkau <nbd@nbd.name>
2023-08-09lib: introduce debug libraryJo-Philipp Wich
Introduce a new debug library which provides introspection facilities for debugging ucode scripts. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2023-08-09treewide: consolidate platform specific code in platform.cJo-Philipp Wich
Get rid of most __APPLE__ guards by introducing a central platform.c unit providing drop-in replacements for missing APIs. Also move system signal definitions into the new platform file to be able to share them with the upcoming debug library. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2023-07-27vm: introduce basic signal handling infrastructureJo-Philipp Wich
Introduce the basic facilities to implement UNIX process signal handling in ucode. The VM structure is extended by a bitmap keeping track of received signal numbers, a sigaction structure which holds a generic signal handler to update the bitmap, a pipe where the generic signal handler will send received signal numbers to and an array of managed signal handler functions, indexed by signal number. Additionally, three new C API functions are added to control signal delivery in the VM instance: - `uc_vm_signal_dispatch()` This function invokes signal handler callbacks for each received signal number, clears the bitmap and empties the pipe. The VM itself will invoke this function after each executed bytecode instruction. In some cases however it is useful for C code driving the VM to force immediate signal delivery, e.g. from within long running C functions that do not return to ucode (to the next bytecode instruction) in a timely manner. - `uc_vm_signal_raise()` This function will deliver the given signal number, so that it is picked up by the next call to `uc_vm_signal_dispatch()`. It is used by the generic C signal handler function to forward received signals to the VM instance. - `uc_vm_signal_notifyfd()` This functions returns the read end of the internal signal pipe. It is mainly useful for integration into select or poll based event loops, in order to be notified when there's pending signals for delivery into the VM instance. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2023-05-30types: implement ucv_object_sort()Jo-Philipp Wich
Introduce a new function `ucv_object_sort()` which works similar to `ucv_array_sort()` and allows reordering the keys of an object. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2023-01-06include: add uc_fn_thisval()Felix Fietkau
Can be used to get rid of a layer of pointer indirection in resource type handlers. Signed-off-by: Felix Fietkau <nbd@nbd.name>
2022-09-30vm: maintain export symbol tables per programJo-Philipp Wich
Instead of having one global export table per VM instance maintain one table per program instance. This is required to avoid clobbering the export list in case `import` using code is loaded at runtime through `require()`, `loadfile()` etc. 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-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-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-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: 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-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-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-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-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>
2022-07-28types: add ability to mark array and object values as constantJo-Philipp Wich
The upcoming module import support requires constant object values to implement module wildcard import. Reuse the existing u64 bit in ucv heads to mark array or object values as constant and add corresponding `ucv_is_constant()` and `ucv_set_constant()` helpers. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2022-07-28lexer: recognize module related keywordsJo-Philipp Wich
Add support for the `import`, `export`, `from` and `as` keywords used in module import and export statements. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2022-07-28lexer: rewrite token scannerJo-Philipp Wich
- Use nested switches instead of lookup tables to detect tokens - Simplify input buffer logic - Reduce amount of intermediate states Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2022-06-30compiler: fix stack mismatch on continue statements nested in switchesJo-Philipp Wich
When compiling continue statements nested in switches, the compiler only emitted pop statements for the local variables in the switch body scope, but not for the locals in the scope(s) leading up to the containing loop body. Extend the compilers internal patchlist structure to keep track of the type of scope tied to the patchlist and extend `continue` statement compilation logic to select the appropriate parent patch list in order to determine the amount of locals (stack slots) to clear before the emitted jump instruction. As a result, the `uc_compiler_backpatch()` implementation can be simplified somewhat since we do not need to propagate entries to parent lists anymore. Also add a further regression test case to cover this issue. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2022-06-01syntax: adjust number literal parsing and string to number conversionJo-Philipp Wich
- Recognize new number literal prefixes `0o` and `0O` for octal as well as `0b` and `0B` for binary number literals - Treat number literals with leading zeros as octal while parsing but as decimal ones on implicit number conversions, means `012` will yield `10` while `+"012"` or `"012" + 0` will yield `12` Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2022-04-13syntax: implement support for ES6 template literalsJo-Philipp Wich
Implement support for ECMAScript 6 template literals which allow simple interpolation of variable values into strings without resorting to `sprintf()` or manual string concatenation. 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-03-31build: add polyfills for older libjson-c versionsJo-Philipp Wich
The libjson-c versions commonly shipped by Debian and Ubuntu lack unsigned 64bit integer support and a number of extended API functions. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2022-03-22lib: provide API function to obtain stdlib function implementationsJo-Philipp Wich
Provide a new API function `uc_stdlib_function()` which allows to fetch the C implementation of the given named standard library function. This is useful for loadable modules or applications that embed ucode which want to reuse core functions such as `sprintf()`. 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-15include: add OS X compatible endian.h headerJo-Philipp Wich
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2022-03-15include: rename include guards to avoid clashes with system headersJo-Philipp Wich
Identifiers starting with one or two underscores are reserved for system headers and toolchain implementations and should not appear in user code. Also on OS X, the ucode __TYPES_H_ guard clashes with the system types.h header. Rename all ucode header guards to avoid such clashes. Supersedes: #43 Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2022-03-07syntax: support add new operatorsJo-Philipp Wich
- Support ES2016 exponentiation (**) and exponentiation assignment (**=) - Support ES2020 nullish coalescing (??) and logical nullish assignment (??=) - Support ES2021 logical and assignment (&&=) and logical or assignment (||=) Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2022-02-07source: convert source objects into proper uc_value_t typeJo-Philipp Wich
Instead of implementing a custom limited refcount logic, turn uc_source_t instances into proper uc_value_t objects. 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>
2022-01-18source: refactor source file handlingJo-Philipp Wich
- Move source object pointer into program entity which is referenced by each function - Move lineinfo related routines into source.c and use them from lexer.c since lineinfo encoding does not belong into the lexical analyzer. - Implement initial infrastructure for detecting source file type, this is required later to differentiate between plaintext and precompiled bytecode files Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2022-01-18compiler, vm: use a program wide constant listJo-Philipp Wich
Instead of storing constant values per function, maintain a global program wide list for all constant values within the current compilation unit. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2022-01-18types: add initial infrastructure for function serializationJo-Philipp Wich
- Introduce a new "program" entity which holds the list of functions created during compilation - Instead of storing pointers to the in-memory function representation in the constant list, store the index of the function within the program's function list - When loading functions from the constant list, retrieve the function by index from the program entity Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2022-01-04vallist: store double values in a platform neutral mannerJo-Philipp Wich
Import the binary64 double packing routines from the struct module and use them to store numeric double values in a platform agnostic big endian format. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2022-01-04treewide: rework numeric value handlingJo-Philipp Wich
- Parse integer literals as unsigned numeric values in order to be able to represent the entire unsigned 64bit value range - Stop parsing minus-prefixed integer literals as negative numbers but treat them as separate minus operator followed by a positive integer instead - Only store unsigned numeric constants in bytecode - Rework numeric comparison logic to be able to handle full 64bit unsigned integers - If possible, yield unsigned 64 bit results for additions - Simplify numeric value conversion API - Compile code with -fwrapv for defined signed overflow semantics Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2021-12-08vm: introduce value registryJo-Philipp Wich
Introduce a new, lazily allocated value registry which can be used by C code to store values which should not be garbage collected. The registry is a plain ucode object internally and treated as GC root but not exposed to ucode script code, this allows it to retain references to values which are otherwise completely unreachable from ucode scripts. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2021-12-07treewide: fix "resource" misspellingsJo-Philipp Wich
Fix various misspelling of "resource". This commit changes the exported libucode ABI. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2021-12-07treewide: fix upvalue reference type nameJo-Philipp Wich
No functional changes. Fixes: ff52440 ("treewide: consolidate typedef naming") Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2021-12-01syntax: disallow keywords in object property shorthand notationJo-Philipp Wich
Signed-off-by: Jo-Philipp Wich <jo@mein.io>