Age | Commit message (Collapse) | Author |
|
- Move source object pointer into program entity which is referenced by
each function
- Move lineinfo related routines into source.c and use them from lexer.c
since lineinfo encoding does not belong into the lexical analyzer.
- Implement initial infrastructure for detecting source file type,
this is required later to differentiate between plaintext and
precompiled bytecode files
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Instead of storing constant values per function, maintain a global program
wide list for all constant values within the current compilation unit.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
- Introduce a new "program" entity which holds the list of functions
created during compilation
- Instead of storing pointers to the in-memory function representation
in the constant list, store the index of the function within the
program's function list
- When loading functions from the constant list, retrieve the function
by index from the program entity
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
When concatenating strings, avoid allocating three times the required
memory in the worst case. Instead of first allocating the string
representations of the operands followed by the memory for the final
string, allocate a string buffer and print the operands into it. This
will grow the target memory as needed and avoid redundant internal
copies of the involved strings.
Also handle the special where the final string fits into a tagged
pointer and deal with it accordingly.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
- Parse integer literals as unsigned numeric values in order to be able
to represent the entire unsigned 64bit value range
- Stop parsing minus-prefixed integer literals as negative numbers but
treat them as separate minus operator followed by a positive integer
instead
- Only store unsigned numeric constants in bytecode
- Rework numeric comparison logic to be able to handle full 64bit
unsigned integers
- If possible, yield unsigned 64 bit results for additions
- Simplify numeric value conversion API
- Compile code with -fwrapv for defined signed overflow semantics
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Introduce a new, lazily allocated value registry which can be used by C
code to store values which should not be garbage collected.
The registry is a plain ucode object internally and treated as GC root
but not exposed to ucode script code, this allows it to retain references
to values which are otherwise completely unreachable from ucode scripts.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Fix various misspelling of "resource".
This commit changes the exported libucode ABI.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
No functional changes.
Fixes: ff52440 ("treewide: consolidate typedef naming")
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Allow querying object properties on resource values. A resource value may
have a prototype object set whose properties should be enumerable.
Support that use case in the VM.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Fix instances of misspelled "resource".
This commit breaks the exported libucode ABI.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
syntax: introduce optional chaining operators
|
|
Introduce new operators `?.`, `?.[…]` and `?.(…)` to simplify looking up
deeply nested property chain in a secure manner.
The `?.` operator behaves like the `.` property access operator but yields
`null` if the left hand side is `null` or not an object.
Like `?.`, the `?.[…]` operator behaves like the `[…]` computed property
access but yields `null` if the left hand side is `null` or neither an
object or array.
Finally the `?.(…)` operator behaves like the function call operator `(…)`
but yields `null` if the left hand side is `null` or not a callable
function.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Reset all callframes when dealing with an unhandled exception to avoid
resuming the code which raised the exception when restarting the VM
later, e.g. through uc_vm_call() or uc_vm_invoke().
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
If execution in an existing VM that threw an exception was resumed
through uc_vm_call() or uc_vm_invoke(), the exception was never cleared,
causing all subsequent calls to return with an exception status as well.
Ensure that any preexisting exception information is discarded before
executing the requested function in order to start from a clean state.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
In success case, always push the function return value onto the stack even
if no call frames are remaining after the function returned.
This is needed for host program code invoking ucode functions within a VM
context that already ran to completion.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
- Ensure that most functions follow the subject_verb naming schema
- Move type related function from value.c to types.c
- Rename value.c to vallist.c
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Provide separate public ucv_gc() and ucv_freeall() functions to perform
an incremental and complete GC run respectively.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Ensure that all custom typedef and vector declaration type names end with
a "_t" suffix.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Add a public getter and setter to read and set the VM trace level
respectively. Use the new API to control the trace mode with a newly
introduced `-t` command line switch.
Drop support for honouring the `TRACE` environment variable as
host programs embedding ucode might want to prevent that behaviour
or handle it differently.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
So far, the VM simply printed exception information to stderr if the
exception was not catched in managed code. Host programs embedding
ucode might want to customize that behaviour, so refactor the current
defualt behaviour into a callback function and add a public getter
and setter to allow changing the exception handler callback.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
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>
|