Age | Commit message (Collapse) | Author |
|
Add a new `isnan()` convenience function to the math library which can
be used to test if a given value is a NaN double.
The same test can be realized without the math library by using a function
similar to the following one:
function isNaN(x) {
return x != x;
}
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
uloop: terminate parent uloop in task child processes
|
|
lib: uc_json(): accept trailing whitespace when parsing strings
|
|
Invoking `sleep(1000)` in the CI container often sleeps slightly longer
than exactly 1000ms, causing the test output to mismatch.
Relax the test requirement to simply ensure that t2 > t1.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Only raise a trailing garbage error if the given JSON source string is
followed by a non white space character.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Ensure that the main process uloop is terminated within task child
processes. Before this fix, using uloop in a task function would
trigger invalid memory accesses in the parent process by notifying
non-existing fd slots in the parent through the inherited shared
epoll descriptor.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
uci: auto-load package in `ctx.foreach()` and `ctx.get_first()`
|
|
compiler: ensure that arrow functions with block bodies return no value
|
|
Functions that use `uci_lookup_ptr()` internally, such as `ctx.get()`,
`ctx.set()` or `ctx.delete()`, implicitly load the given configuration
name while the higher level functions `ctx.foreach()` or `ctx.get_first()`
do not.
This behaviour violates the principle of least surprise and might lead to
non-deterministic program behavior as the outcome of these functions
depends on prior uci operations performed on the cursor.
Fix this issue by invoking `uci_load()` internally in case the given
uci package name cannot be found in the cursor's package cache.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Follow ES6 semantics and ensure that arrow functions with a block body
don't implicitly return the value of the last executed statement.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
compiler: fix `??=`, `||=` and `&&=` logical assignment sementics
|
|
When compiling logical assignment expressions, ensure that the right hand
side of the assignment is not evaluated when the assignment condition is
unfulfilled.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
add cmake to install requires for debian
|
|
|
|
fs: expose `getdelim()` functionality through `fd.read()`
|
|
When `fd.read()` is invoked with a single-character string argument,
invoke `getdelim()` internally to read the input until the give character
or EOF. This is useful for reading character delimited input data.
For example `fd.read('\n')` will read any data up to the first newline
(or EOF) while `fd.read('\0x00')` will read until the first null byte.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
fs: use `getline()` for line wise read operations
|
|
lexer: fixes for regex literal parsing
|
|
Use `getline()` instead of a custom `fgets()` wrapper logic to perform
line wise reads from open file handles. This is required to properly
deal with lines containing embedded null bytes.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
- Ensure that regexp extension escapes are consistently handled;
substitute `\d`, `\D`, `\s`, `\S`, `\w` and `\W` with `[[:digit:]]`,
`[^[:digit:]]`, `[[:space:]]`, `[^[:space:]]`, `[[:alnum:]_]` and
`[^[:alnum:]_]` character classes respectively since not all POSIX
regexp implementations implement all of those extensions
- Preserve `\b`, `\B`, `\<` and `\>` boundary matches
Fixes: a45f2a3 ("lexer: improve regex literal handling")
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
lib: implement slice() function
|
|
Implement a new function `slice()` to complement the existing `splice()`
function and model it's semantics after the ES6 `Array.slice()` version.
Fixes: #106
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Various improvements
|
|
Introduce a new `-p` flag which works like `-e` but prints the final
expression result.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Track last emitted statement type in compiled code and only generate final
`return null` opcodes if there is no preceeding `return` statement.
Also use this statement tracking to avoid emitting invalid return opcodes
for arrow function bodies with trailing empty statements.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
- Do not treat slashes within bracket expressions as delimitters
- Do not escape slashes when stringifying regex sources
- Allow all escape sequence types in regex literals
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
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>
|
|
Both input and output callbacks for uloop tasks are optional, but the
low level io callback implementation did not properly deal with an absent
ucode output callback, triggering an exception in managed code due to
invoking a null value as function.
Fix this issue by checking for the availability of a callable output
function and simply discarding the received task message otherwise.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Prevent GC'ing (and thus tearing down) an active ubus connection as long as
there's still unfinished deferred request contexts alive.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
ubus: various improvements
|
|
Some ubus users require access to the original ubus error status returned
by various operations for fine grained error handling.
Extend the error() function with an optional boolean argument which causes
the function to return the numeric error code instead of a preformatted
message when invoked.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Add constants for ubus status codes to the toplevel module scope in order
to avoid the need for magic values in the code.
Suggested-by: Felix Fietkau <nbd@nbd.name>
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
The implicit return style for sending ubus method replies currently always
emits an UBUS_STATUS_NO_DATA code in case neither req.reply() was called,
nor a deferred or object were returned by the handler function.
This slightly complicates the implementation of handlers that do not wish
to send reply data but simply acknowledge the request with an
UBUS_STATUS_OK code.
In order to simplify this use case, allow handlers to override the default
status by treating integer return values as ubus error codes.
After this change, the following handler:
function (request) {
/* do some work */
request.reply(null, 0);
}
... can be rewritten as:
function (request) {
/* do some work */
return 0;
}
Suggested-by: Felix Fietkau <nbd@nbd.name>
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Extend the split() and replace() functions to accept an additional optional
`limit` argument which limits the amount of split operations / substitutions
performed by these functions.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
fs: add optional third permission argument to fs.open()
|
|
lib: remove fixed capture group limit in match() and regex replace()
|
|
Rework the `fs.open()` implementation to accept an optional third file
permission argument which is applied to newly created files.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
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>
|
|
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>
|
|
- 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>
|
|
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>
|
|
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>
|
|
lib: introduce three new functions call(), loadstring() and loadfile()
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|