Age | Commit message (Collapse) | Author |
|
For string cases, turn `int()` into a thin `strtoll()` wrapper which
attempts to parse the initial portion of the string as a decimal integer
literal, optionally preceded by white space and a sign character.
Also introduce an optional `base` argument for string cases while we're
at it and adjust the existing stdlib test case accordingly.
The function now behaves mostly the same as ECMAScript `parseInt(val, 10)`
for string cases, means it will recognize `012` as `12` and not `10` and
it will accept trailing non-digit characters after the initial portition
of the input string.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
ci: make jobs faster during pull request testing
|
|
lib: rework uc_index() implementation
|
|
- Fix segfault on passing string haystack with non-string needle argument
- Perform strict equality tests against array haystacks
- Make string searches binary safe
- Improve left index string search performance
- Improve right index array search performance
- Add missing test coverage for index() and rindex()
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
When compiling expressions followed by a unary operator, the compiler
triggered a segmentation fault due to invoking an unset infix parser
routine.
Explicitly handle this case and raise a syntax error if such an
invalid expression is encountered.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
If the read limit passed to fs.readfile() is smaller than BUFSIZ then
disable stdio input buffering to avoid overreading the underlying file.
This is useful when reading small amounts of data from special files
such as /dev/urandom, where a readfile call limited to 16 bytes might
actually read 4096 due to stdio buffering.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
lib: introduce hexenc() and hexdec()
|
|
Add two new functions to deal with encoding and decoding of hexadecimal
digit strings:
- hexenc() - convert the given input value into a lower case hex digit
string, implicitely converting the input argument to a string value
if needed
- hexdec() - decode the given input hex digit string into a byte string,
skipping whitespace or optionally specified characters in the input
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
With the proliferation of test cases, CI runs tend to become rather long
since we run all tests under valgrind using multiple gcc and Clang
versions each.
In order to speedup the jobs, we tests pull requests under the most
recent Clang versions and run all tests when the code hits the master
branch.
Closes #66
Signed-off-by: Petr Štetiar <ynezz@true.cz>
|
|
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
syntax: implement support for ES6 template literals
|
|
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>
|
|
vm: stop executing bytecode on return of nested calls
|
|
When a managed function is indirectly invoked during bytecode execution,
e.g. when calling the tostring() method of an object prototype during
string concatenation, the invoked function must stop executing bytecode
upon return to hand control back to caller.
Extend `uc_vm_execute_chunk()` to track the amount of nested function
calls it performs and hand back control to the caller once the toplevel
callframe returns. Also bubble unhandled exceptions only as far as up
to the original caller.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
treewide: move json-c compat shims into internal header file
|
|
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>
|
|
|
|
lib: let `json()` accept input objects implementing `read()` method
|
|
Move the invocation of the unhandled exception callback handler out of
`uc_vm_execute_chunk()` into both `uc_vm_execute()` and `uc_vm_invoke()`
in order to consistently report exceptions exactly once regardless of
whether a native or managed code function is executed as topmost VM
call.
This solves cases where the unhandled exception callback was either
called multiple times or never at all.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
When invoking a native function as toplevel VM call which indirectly
triggers an unhandled exception in managed code, the callframes are
completely reset before the C function returns, leading to invalid
memory accesses when `uc_vm_call_native()` subsequently popped it's
own callframe again.
This issue did not surface by executing script code through the
interpreter since in this case the VM will always execute a managed
code as toplevel call, but it could be triggered by invoking a native
function triggering an exception through the C API using `uc_vm_call()`
on a fresh `uc_vm_t` context or by utilizing the CLI interpreters `-l`
flag to preload a native code library triggering an exception.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Do not continue loading other libraries or executing the main code if
loading one of the preload libraries fails.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
fs: implement `fs.readfile()` and `fs.writefile()`
|
|
Extend the `uc_json()` implementation to accept readable objects in
addition to plain input strings. This allows parsing JSON input directly
from open file handles, sockets or other kinds of producer objects without
the need to store the entire JSON source string intermediately in memory.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
The `fs.readfile()` and `fs.writefile()` functions allow efficient reading
and writing of whole files, reducing the required boilerplace code compared
to using the `open()`/`read()`/`write()`/`close()` API.
- `fs.readfile()` takes two arguments; the path to open and an optional
limit value. If limit is omitted, `null` or negative, the entire file
contents are read, otherwise the specified amount of bytes. Returns the
read file contents as string or `null` on error.
- `fs.writefile()` takes three arguments; the path to open/create, the
contents to write and an optional limit value. If limit is omitted, the
entire content is written, otherwise just the specified amount of bytes.
Non-string content arguments are internally converted to strings, `null`
is treated as empty string. Returns the amount of bytes written or `null`
on error.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Fixes: dfaf05a ("ci: debian: automatically update changelog from Git tag")
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
fs: fix off-by-one in fs.dirname() function
|
|
Debian package build
|
|
Make sure fs.dirname() doesn't truncate the last character of the
returned path. Previously ucv_string_new_length was called with a
length which no longer included the last character (which had just
been tested not to be a '/' or '.' and hence broke the loop at that
point).
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
[testcase added]
Signed-off-by: Paul Spooren <mail@aparcar.org>
[testcase folded into this commit and fixed]
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
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>
|
|
Signed-off-by: Paul Spooren <mail@aparcar.org>
|
|
This adds Debian packages for the ucode interpreter, the runtime library,
development headers and extension modules.
Fixes: #55
Signed-off-by: Paul Spooren <mail@aparcar.org>
[split into multiple packages, pass SOVERSION to the build]
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Treat the char value as unsigned when testing its value to yield consistent
results on both platforms with signed chars and those with unsigned chars
by default (e.g. ARM ones). This also avoids encoding byte values > 127 as
\uXXXX escape sequences, potentially breaking the strng contents.
Fixes: #62
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
uloop: add support for tasks
|
|
lib: add date and time related functions
|
|
Add five new functions to deal with date calculation and timing:
- localtime(), gmtime() - return a broken down calendar date and time
specification from the given epoch (or now, if absent) in local and
UTC time respectively
- timelocal(), timegm() - the inverse operation for the former functions,
taking a date and time specification (interpreted as local or UTC time
respectively) and turning it into an epoch value
- clock() - return the second and nanosecond values of the system clock,
useful for time/performance measurements
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
lib: provide API function to obtain stdlib function implementations
|
|
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>
|
|
main: turn ucode into multicall executable
|
|
Turn the ucode executable into a multicall binary and select default flags
based on the name it was invoked with. Introduce two new symlinks "ucc" and
"utpl" which start ucode in compile and template mode respectively.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Tasks are similar to processes but instead of executing a new process, an
ucode function is invoked instead, running independently of the main
process.
Example usage:
uloop.init();
let t = uloop.task(
// program function
function(pipe) {
let input = pipe.receive();
pipe.send({ got_input: input });
return { result: true };
},
// parent recv function, invoked when task function calls pipe.send()
function(res) {
printf("Received output message: %.J\n", res);
},
// parent send function, invoked when task function calls pipe.receive()
function() {
let input = { test: "Example" };
printf("Sending input message: %.J\n", input);
return input;
}
);
uloop.run();
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Build minimal version to detect compile issues.
Signed-off-by: Paul Spooren <mail@aparcar.org>
|
|
lib: add argument position support (`%m$`) to `sprintf()` and `printf()`
|