Age | Commit message (Collapse) | Author |
|
When a function is invoked directly, e.g. through uc_vm_invoke(), the call
stack is empty, so avoid accessing the first call frame unless we actually
need to, which is only the case if the function is invoked with spread args
which can only happen with calls from manged code.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
When a toplevel function call raises an exception, the call stack will be
empty when invoking the exception handler, ensure to handle this case
appropriately.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Instead of invoking exit(3) from uc_exit(), use a new EXCEPTION_EXIT
exception type to instruct the VM to shutdown cleanly.
This is required to not terminate the host program in case libucode
is embedded and loaded scripts invoke the exit() function.
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 uc_vm_invoke() function simplifies calling a named ucode function with
arbitrary arguments.
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>
|
|
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
If there's only native function calls on the call stack, the code
incorrectly accessed an invalid memory location.
Avoid that issue by stopping the search for non-native callframes
before the last frame.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Since we need to ensure that NaN values are properly handled, we cannot
transform `x <= y` and `x >= y` into `!(x > y)` and `!(x < y)` respectively.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
This allows us to drop some token->instruction mapping case switches
in the VM.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Ensure that relational operators in the lexer token and vm instruction
lists are both ordered in the same way according to the general operator
precedence of the grammar.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Turn `delete` into a proper operator mimicking ECMAScript semantics.
Also ensure to transparently turn deprecated `delete(obj, propname)`
function calls into `delete obj.propname` expressions during compilation.
When strict mode is active, legacy delete() calls throw a syntax error
instead.
Finally drop the `delete()` function from the stdlib as it is shadowed
by the delete operator syntax now.
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>
|
|
syntax: implement support for 'use strict' pragma
|
|
Support per-file and per-function `"use strict";` statement to opt into
strict variable handling from ucode source code.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
- Shuffle typedefs to avoid need for non-compliant forward declarations
- Fix non-compliant empty struct initializers
- Remove use of braced expressions
- Remove use of anonymous unions
- Avoid `void *` pointer arithmetic
- Fix several warnings reported by gcc -pedantic mode and clang 11 compilation
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Print "Before start of program" for errors that are raised before entering
main(), e.g. on module preloading failure.
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>
|
|
Instead of relying on json_object values internally, use custom types to
represent the different ucode value types which brings a number of
advantages compared to the previous approach:
- Due to the use of tagged pointers, small integer, string and bool
values can be stored directly in the pointer addresses, vastly
reducing required heap memory
- Ability to create circular data structures such as
`let o; o = { test: o };`
- Ability to register custom `tostring()` function through prototypes
- Initial mark/sweep GC implementation to tear down circular object
graphs on VM deinit
The change also paves the way for possible future extensions such as
constant variables and meta methods for custom ressource types.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
- Fix an off-by-one when printing push/pop stack indexes
- Properly print negative hexadecimal values
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Fixes: 20a3763 ("vm: fix loop variable memory leak in NEXTK/NEXTKV instruction")
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>
|
|
Before this fix, the VM aborted due to an assert in libjson-c when an
attempt was made to set a property on a non-object value.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
The uc_vm_execute() API function decreases the refcount of the globals
object when finishing but does not increase it initially which leads to
a double free at main.c:155
Fix the issue by both increasing and decreasing the refcount.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Replace the former AST walking interpreter implementation with a single pass
bytecode compiler and a corresponding virtual machine.
The rewrite lays the groundwork for a couple of improvements with will be
subsequently implemented:
- Ability to precompile ucode sources into binary byte code
- Strippable debug information
- Reduced runtime memory usage
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|