Age | Commit message (Collapse) | Author |
|
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>
|
|
Instead of obtaining and caching direct opcode pointers, use relative
references when dealing with opcodes since direct or indirect calls to
uc_execute_op() might lead to reallocations of the opcode array, shifting
memory addresses and invalidating pointers taken before the invocation.
Such stale pointer accesses could be commonly triggered when one part
of the processed expression was a require() or include() call loading
relatively large ucode sources.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Optimize the strncmp() based token lookup with an integer comparison
approach which roughly cuts the time of the source code parsing phase
in half.
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>
|
|
Also handle calls to C functions.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Store the invocation scope and function context in the call stack frame
and not in the function object to properly deal with recursive invocations.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Get rid of the distinction between lexer/parser errors and runtime
exceptions, use exceptions everywhere instead.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
- Keep an open FILE* reference to processed source files in order to
be able to rewind and extract error context later
- Build a proper call stack when invoking utpl functions
- Report call stack in exceptions
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Rewrite the lexer into a restartable state machine to support parsing from
file streams without the need to read the entire source text into memory
first.
As a side effect, the length of labels and strings is unlimited 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>
|
|
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
- Implement proper closure scoping for function
- Avoid circular references when managing scopes pointers
- Eliminate ut_putval() in favor to json_object_put()
- Fix function return value handling
- Change internal function structure
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
We cannot use direct pointers since the opcode array might be reallocated
resulting in potentially changed memory addresses.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Instead of propagating failures to the caller, print a generic error
message and terminate program execution through abort().
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
The `%J` format allows outputting values as valid JSON string.
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>
|
|
Register prototype object directly together with the type instead of
setting it manually whenever an extended type value is instantiated.
This also allows freeing the various prototype objects in dlopened
modules.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
This reverts commit 54bb15b2be3656e91386b80074f45591b20fed3f.
Relying on setjmp() / longjmp() causes too many headaches trying to track
and properly release intermediate values.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Use setjmp() and longjmp() to deal with runtime exceptions.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
- Support `for (var x in ...)` syntax
- Support `for (var i = 0; i < ...; i++)` syntax
- Properly handle "for" loops without condition and increment expression
- Reject for-in loops with invalid lhs
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
The ut_is_type() function simplifies checking the extended tag type of a
given JSON object value.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Also introduce convenience macro for registering function arrays in modules.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
The current code still abused the JSON value pointer to denote postfix
access for certain operations which led to a crash when freeing the
parser state due to an attempt to put a (void *)1 pointer.
Since we do have the ability to set flags on operations since the AST
rework, use this much cleaner approach and avoid the invalid pointer
hackery.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
This allows number literals that exceed the range INT64_MIN..INT64_MAX
to be truncated to the respective min and max values in a defined manner.
It also makes it possible to have the expression `{{ -9223372036854775808 }}`
actually result in `-9223372036854775808`. Since negation and number
declaration are separate operations, the value would be first truncated to
`9223372036854775807` and then negated, making it impossible to write a
literal INT64_MIN value without tracking the overflow.
Also fix the number parsing logic to not trucate intergers to 32bit.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
- unify operand and value tag structures
- use a contiguous array for storing opcodes
- use relative offsets for next and children ops
- defer function creation to runtime
- rework "this" context handling by storing context pointer in scope tags
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
In order to implement prototype chains later on, introduce a tagged object
value type and use it when processing object declarations.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Support a new keyword `this` which allows functions to access the context
they're called upon.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|