summaryrefslogtreecommitdiffhomepage
path: root/include
AgeCommit message (Collapse)Author
2024-12-02types, vm: refactor usage of global variablesJo-Philipp Wich
Introduce an extensible private TLS context structure and use it within libucode to store global state such as active object iterators. This allows using libucode concurrently in multiple threads without unintentionally sharing global state among them. Also adjust the signal dispatching setup logic in `uc_vm_init()` to only enable signal handling if no other VM in the same thread already handles signals. Suggested-by: Isaac de Wolff <idewolff@vincitech.nl> [squash commits, move signal handler vm pointer and object iterator list into common extensible TLS context, whitespace and naming adjustments, extended signal setup logic] Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2024-12-02types: introduce `ucv_array_sort_r()` and `ucv_object_sort_r()`Jo-Philipp Wich
Introduce two new functions for ordering arrays and object keys which utilize a different compare callback signature and allow passing a user provided pointer to the comparison callback. The main advantages of the `ucv_*_sort_r()` flavors are the ability to pass custom context to comparisons via the user data pointer and the invocation of the comparison callback with direct `uc_value_t *` pointers instead of opaque `const void *` arguments pointing to `uc_value_t *` or json-c internal `struct lh_entry *` pointers respectively. Suggested-by: Isaac de Wolff <idewolff@vincitech.nl> [align naming and whitespace with the rest of the codebase, rename some variables for clarity, group sort related changes into two commits, drop constness from `uc_value_t *` compare function arguments] Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2024-10-24types: add ucv_resource_create() helperJo-Philipp Wich
Introduce a new inline convenience function ucv_resource_create() which simplifies creating resource values by resource type name by combining resource type lookup and resource value creation in one call. This function will be used in subsequent refactoring to eliminate global static variables. Suggested-by: Isaac de Wolff <idewolff@vincitech.nl> [separated from original commit, move ucv_resource_create() into types.h] Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2024-10-23nl80211: add new attributes for multi-radio supportFelix Fietkau
- vif radio mask: used to assign vifs to specific radios - monitor skip_tx flag: do not pass locally transmitted packets on the monitor interface - radio antenna mask: radio specific part of the phy antenna mask Signed-off-by: Felix Fietkau <nbd@nbd.name>
2024-10-18Merge pull request #213 from jow-/improve-vector-macrosJo-Philipp Wich
utils: improve vector macros
2024-10-18utils: improve vector utilitiesJo-Philipp Wich
This commits introduces a number of new helper macros to deal with vectors and refactors the existing code for better resource utilization. The allocation strategy is changed from multiple of 8 to exponential growth by factor 1.5 in order to minimize the number of reallocations and potentially needed memory copies. The newly introduced macros are: - uc_vector_capacity(init_capacity, add_items) Derive the resulting vector capacity from the given item count and initial capacity. - uc_vector_extend(vector, add_items) Increase vector capacity by given amount of items, zero-initialize added capacity and return pointer to first new item past the current length. - uc_vector_reduce(vector, remove_items) Reduce vector capacity by given amount of items. - uc_vector_pop(vector) Return pointer to last element and decrement count, or NULL if the vector is empty. - uc_vector_foreach(vector, itervar) A for() loop wrapper to iterate vectors, providing an iter variable to the loop body. - uc_vector_foreach_reverse(vector, itervar) A for() loop wrapper to iterate vectors backwards, providing an iter variable to the loop body. The uc_vector_push() macro has been changed into a variadic macro which internally prefixes the argument list with a cast to the vector element type, allowing user to pass compound expressions like struct initializers in order to simplify adding elements: uc_vector_push(&my_collection, { .foo = 1, .bar = "qrx" }); Like uc_vector_pop(), the uc_vector_last() macro has been made safe to use on empty vectors, it'll now return NULL in this case. Finally the vector realloc logic was moved into static functions within the header file, allowing all vector using code of a compilation unit to share the reallocation, shrinking the size of libucode.so by 1-2KB as a side effect. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2024-10-17types: fix potential use after free on adding keys during iterationJo-Philipp Wich
When keys are added to the object currently being iterated by a for loop, the insert operation might cause a hashtable resize with a subsequent memory reallocation and a different table base pointer, clobbering the entry pointers held by iterators pointing to the containing object of the resized table. In order to address this issue while keeping the iteration overhead low, extend the object key insert logic to check whether the insertion will trigger a reallocation and backup and restore the iterator pointers when needed. This slightly increases the size of the iterator states but the overhead for this should be neglectible as there'll only be a low amount of concurrently active iterations at any time. Fixes: #230 Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2024-09-23lexer: make api functions publicJo-Philipp Wich
Make the lexer API functions `uc_lexer_init()`, `us_lexer_free()` and `uc_lexer_next_token()` public for use in loadable extensions. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2024-09-23lexer: emit comment and template statement block tokensJo-Philipp Wich
Tweak the token stream reported by the lexer in order to make it more useful for alternative, non-compilation downstream parse processes such as code intelligence gathering within a language server implementation. - Instead of silently discarding source code comments in the lexing phase, emit TK_COMMENT tokens which is useful to e.g. parse type annotations and other structured information. - Do not silently discard TK_LSTM tokens but report them to downstream parsers instead. - Do not silently emit TK_RSTM tokens as TK_SCOL but report them as-is to downstrem parsers. - Adjust the byte code compiler to properly deal with the changed token reporting by discarding incoming TK_COMMENT and TK_LSTM tokens and by remapping read TK_RSTM tokens to the TK_SCOL type. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2024-09-23lexer: improve token position reportingJo-Philipp Wich
- Report end position for emitted tokens. This is required to reliably determine the token length, e.g. for downstream code intelligence use cases - Fix start offset of continued template literal string tokens. Previously the start offset of a literal string following a `${...}` placeholder expressions was shifted by one byte - Report proper start offset of `TK_LEXP` tokens. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2024-07-11nl80211: support the MAC80211_HWSIM netlink protocol familyJo-Philipp Wich
The mac80211_hwsim module exposes a custom generic netlink family for managing simulated phys and userspace data frame transmission. Since hwsim functionality is closely related to nl80211 and useful to e.g. manage simulated wireless testbeds, I decided to include support directly into the nl80211 module. Example calls for creating and destroying hwsim wiphys: nl80211.request(nl80211.const.HWSIM_CMD_NEW_RADIO, 0, { perm_addr: "02:11:22:33:44:55", support_p2p_device: true }); nl80211.request(nl80211.const.HWSIM_CMD_DEL_RADIO, 0, { radio_name: "phy2" }); Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2024-07-09nl80211: update nl80211.h to latest wireless-nextFelix Fietkau
Includes the new attributes for wiphy multi-radio support Signed-off-by: Felix Fietkau <nbd@nbd.name>
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>