Age | Commit message (Collapse) | Author |
|
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>
|
|
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>
|
|
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>
|
|
- 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>
|
|
utils: improve vector macros
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
- 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>
|
|
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>
|
|
Includes the new attributes for wiphy multi-radio support
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|
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>
|
|
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>
|
|
Accept char * const *, cast internally. Fixes a compile error
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|
Introduce a new debug library which provides introspection facilities
for debugging ucode scripts.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
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>
|
|
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>
|
|
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>
|
|
Can be used to get rid of a layer of pointer indirection in resource type
handlers.
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
- 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>
|
|
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>
|
|
- 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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
We now include `json-c/json-c.h` on all supported environments.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
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>
|
|
- 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>
|
|
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>
|