Age | Commit message (Collapse) | Author |
|
The I_DYNLOAD opcode is basically a bytecode level instruction for
uc_require() with semantics similar to I_IMPORT. It allows loading
a dynamic extension library at runtime and treating values from the
resulting module context object like exports from a compile time source
module.
For example the statement `import { readfile, writefile } from "fs"`
would import the readfile() and writefile() functions of fs.so as
readonly live bindings into the current file scope.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Break out the core logic of the uc_require() stl function into a new
uc_require_library() helper function and make it available for usage
outside of lib.c. Also add a new boolean parameter to the helper function
which allows restricting runtime require operations of modules to dynamic
libraries only.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Try to resolve the source offset to line and character position and only
fall back to report the location as instruction offset if we weren't able
to determine the line number.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
If a compile error is raised at offset 0, try to resolve line and
character position anyway.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
|
|
Indent inner messages and prepend them with a vertical bar to increase
visual separation of messages. Also include file name in source context
output when the compiled program contains more than one source file.
Adjust affected testcase outputs accordingly.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Since we track the offsets in the compiler directly now there's no need
to keep this function.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
The current implementation of the module export offset tracking was
inadequate and failed to properly handle larger module dependency
graphs. In order to properly support nested module imports/exports,
the following changes have been introduced:
- Gather export slots during module compilation and emit corresponding
export opcodes as one contiguous block at the end of the module
function body, right before the final return. This ensures that
interleaved imports of other modules do not place foreign exports
between our module exports.
- Track the number of program wide allocated export slots in order
to derive per-module-source offsets for the global VM export list.
- Derive import opcode source index from the module source export
offset and the index of the requested name within the module source
export name list.
- Improve error reporting for circular module imports.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
The current implementation of `uc_compiler_canonicalize_path()` used the
entire runtime path of the source object as path prefix, not just the
directory part of it.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
- Disallow toplevel `return` statements in module functions
- Disallow `export` statements in non-module functions
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Module function upvalues are patched through import operations, ensure to
leave them uninitialized when loading and executing the module constructor.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Introduce a further uc_function_t structure member indicating whether the
underlying function is a module constructor.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Module import export support
|
|
Trim down the libucode.so size somewhat by marking purely internal,
non-public API functions hidden.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
This commit introduces syntax level support for ES6 style module import
and export statements. Imports are resolved at compile time and the
corresponding module code is compiled into the main program.
Also add testcases to cover import and export statement semantics.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Do not require a parent function compiler reference to lookup an already
declared (potentially unresolved) upvalue in the current scope. Instead,
search the named upvalues in the current function scope in case there is
no parent compiler reference.
This is required for the upcoming module support which will use unresolved
upvalues to realize import/export functionality.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
So far we allowed anonymous toplevel function expressions which makes
little sense since those can't be used for anything.
Require toplevel function declarations to be named and turn a missing
name into a compile time syntax error.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Report the proper source location when raising an error due to an
increment/decrement operation on a constant value.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Replace all occurrences for the test file directory path with "." in stderr
and stdout results to ensure stable test outputs.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
The upcoming compile-time module support will require the configured
extension search path in the compiler as well, so move it to the
already shared uc_parse_config_t structure and add the appropriate
utility functions to initialize, append and free the search path
vector.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Introduce new opcodes to realize module imports and exports. The export
operation will capture a local variable as upvalue and store it in VM
wide module export registry while the import operation will connect an
upvalue from the module export registry with a preallocated upvalue in
the running function scope.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Reject modifications on object and array values with a type exception when
the constant flag is set on the value operated upon.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Resolve upvalue references to their actual values when pushing such
references onto the stack (or when attempting to call them as method).
This allows constructing objects of pointers, as needed for wildcard
module imports.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Upcoming module support will rely on upresolved upvalues which are patched
at runtime to realize module imports, make sure the VM trace code does not
choke on such unresolved upvalues.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Add a helper function to query the global index of a named export within
a specific source which is a prerequisite for compiling import statements.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
The upcoming module support requires maintaining multiple source objects
within the same program, so add the necessary infrastructure for it.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
We must always report the chunk source position relative to the function
start offset, even if it is zero.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
The sizeof(size_t) might differ from the sizeof(uint32_t) used to serialize
compiled bytecode, so extra care is needed to properly encode and decode
upvalue slot values which are defined as (size_t)-1 / 2 + n.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Extend abstract source objects to maintain a list of exported symbols and
add functions to append and lookup exported names.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Reject modifications on array values with a type exception when
the constant flag is set on the array operated upon.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
When stringifying upvalue references, resolve their target value and
convert it to a string. Only yield the abstract string representation
if the target value cannot be resolved.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
The upcoming module import support requires constant object values to
implement module wildcard import.
Reuse the existing u64 bit in ucv heads to mark array or object values
as constant and add corresponding `ucv_is_constant()` and
`ucv_set_constant()` helpers.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Add support for the `import`, `export`, `from` and `as` keywords used in
module import and export statements.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
- Use nested switches instead of lookup tables to detect tokens
- Simplify input buffer logic
- Reduce amount of intermediate states
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
lexer: fix parsing with disabled block left stripping
|
|
rtnl: fix parsing/creation of IFLA_AF_SPEC RTA for the AF_BRIDGE family
|
|
When a template was parsed with global block left stripping disabled, then
any text preceding an expression or statement block start tag was incorrectly
prepended to the first token value of the block, leading to syntax errors in
the compiler.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Some pecularities in the encoding of the IFLA_AF_SPEC attribute make it
unsuitable for table driven parsing/generation.
To solve this issue, introduce specific datatype handling for IFLA_AF_SPEC
and parse/generate the RTA depending on the address family of the containing
netlink message.
Also add some missing constants while we're at it.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
compiler: fix stack mismatch on continue statements nested in switches
|
|
When compiling continue statements nested in switches, the compiler only
emitted pop statements for the local variables in the switch body scope,
but not for the locals in the scope(s) leading up to the containing loop
body.
Extend the compilers internal patchlist structure to keep track of the
type of scope tied to the patchlist and extend `continue` statement
compilation logic to select the appropriate parent patch list in order
to determine the amount of locals (stack slots) to clear before the
emitted jump instruction.
As a result, the `uc_compiler_backpatch()` implementation can be simplified
somewhat since we do not need to propagate entries to parent lists anymore.
Also add a further regression test case to cover this issue.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
ubus: end uloop on exceptions in managed code
|
|
uloop: end uloop on exceptions in managed code
|
|
Instead of silently continuing, end the uloop when encountering exceptions
in ucode callbacks to let those exceptions propagate to the host program.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Instead of silently continuing, end the uloop when encountering exceptions
in ucode callbacks to let those exceptions propagate to the host program.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
rtnl: expose IFLA_STATS64 contents
|
|
Decode IFLA_STATS64 attribute and make contained counters available to ucode.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
rtnl: expose ifinfomsg.ifi_change member
|
|
For certain operations, such as bringing up interfaces, it is required to
initialize the ifi_change mask in the ifinfomsg struct.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
rtnl: update NETLINK_GET_STRICT_CHK socket flag with every request
|