summaryrefslogtreecommitdiffhomepage
path: root/include
AgeCommit message (Collapse)Author
2023-05-30types: implement ucv_object_sort()Jo-Philipp Wich
Introduce a new function `ucv_object_sort()` which works similar to `ucv_array_sort()` and allows reordering the keys of an object. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2023-01-06include: add uc_fn_thisval()Felix Fietkau
Can be used to get rid of a layer of pointer indirection in resource type handlers. Signed-off-by: Felix Fietkau <nbd@nbd.name>
2022-09-30vm: maintain export symbol tables per programJo-Philipp Wich
Instead of having one global export table per VM instance maintain one table per program instance. This is required to avoid clobbering the export list in case `import` using code is loaded at runtime through `require()`, `loadfile()` etc. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2022-08-24lib: introduce helper function for indenting error messagesJo-Philipp Wich
Factor out the nested syntax error message indentation logic into a separate helper procedure for reuse in other places. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2022-08-12vm: support automatic periodic GC runsJo-Philipp Wich
Introduce two new VM api functions uc_vm_gc_start() and uc_vm_gc_stop() which allow starting and stopping automatic periodic garbage collection of cyclic objects in the VM context. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2022-08-06compiler: add import statement support for dynamic extensionsJo-Philipp Wich
Utilize the new I_DYNLINK vm opcode to support import statements referring to dynamic extension modules. During compilation, the compiler will try to infer the type of the imported module from the resolved file path; if it ends with `.so`, the module is assumed to by a dynamic extension and loading/binding of the module is deferred to runtime using I_DYNLINK opcodes. Additionally, the `-c` cli option gained support for a new compiler flag `dynlink=...` which allows forcing a particular module name expression to be treated as dynamic extension. This is useful to e.g. force resolving `import { x } from "foo"` to a dynamic extension `foo.so` loaded at runtime even if a plain `foo.uc` exists in the search path during compilation or if no such module is available at build time. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2022-08-06vm: introduce new I_DYNLOAD opcodeJo-Philipp Wich
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>
2022-08-06lib: internally expose new uc_require_library() helperJo-Philipp Wich
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>
2022-08-05program: remove now unused uc_program_export_lookup()Jo-Philipp Wich
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>
2022-08-05compiler: rework export index allocationJo-Philipp Wich
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>
2022-08-05compiler: add a flag denoting module functionsJo-Philipp Wich
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>
2022-07-30treewide: unexport libucode internal functionsJo-Philipp Wich
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>
2022-07-30compiler: add support for import/export statementsJo-Philipp Wich
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>
2022-07-30vm, cli: move search path into global configuration structureJo-Philipp Wich
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>
2022-07-30vm: introduce import and export opcodesJo-Philipp Wich
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>
2022-07-30program: add function to globally lookup exported nameJo-Philipp Wich
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>
2022-07-30program: add infrastructure to handle multiple sources per programJo-Philipp Wich
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>
2022-07-30source: add tracking of exported symbolsJo-Philipp Wich
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>
2022-07-28types: add ability to mark array and object values as constantJo-Philipp Wich
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>
2022-07-28lexer: recognize module related keywordsJo-Philipp Wich
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>
2022-07-28lexer: rewrite token scannerJo-Philipp Wich
- 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>
2022-06-30compiler: fix stack mismatch on continue statements nested in switchesJo-Philipp Wich
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>
2022-06-01syntax: adjust number literal parsing and string to number conversionJo-Philipp Wich
- Recognize new number literal prefixes `0o` and `0O` for octal as well as `0b` and `0B` for binary number literals - Treat number literals with leading zeros as octal while parsing but as decimal ones on implicit number conversions, means `012` will yield `10` while `+"012"` or `"012" + 0` will yield `12` Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2022-04-13syntax: implement support for ES6 template literalsJo-Philipp Wich
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>
2022-04-07treewide: move json-c compat shims into internal header fileJo-Philipp Wich
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>
2022-03-31build: add polyfills for older libjson-c versionsJo-Philipp Wich
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>
2022-03-22lib: provide API function to obtain stdlib function implementationsJo-Philipp Wich
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>
2022-03-15treewide: remove legacy json-c include directivesJo-Philipp Wich
We now include `json-c/json-c.h` on all supported environments. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2022-03-15include: add OS X compatible endian.h headerJo-Philipp Wich
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2022-03-15include: rename include guards to avoid clashes with system headersJo-Philipp Wich
Identifiers starting with one or two underscores are reserved for system headers and toolchain implementations and should not appear in user code. Also on OS X, the ucode __TYPES_H_ guard clashes with the system types.h header. Rename all ucode header guards to avoid such clashes. Supersedes: #43 Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2022-03-07syntax: support add new operatorsJo-Philipp Wich
- Support ES2016 exponentiation (**) and exponentiation assignment (**=) - Support ES2020 nullish coalescing (??) and logical nullish assignment (??=) - Support ES2021 logical and assignment (&&=) and logical or assignment (||=) Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2022-02-07source: convert source objects into proper uc_value_t typeJo-Philipp Wich
Instead of implementing a custom limited refcount logic, turn uc_source_t instances into proper uc_value_t objects. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2022-02-07treewide: rework function memory modelJo-Philipp Wich
- Instead of treating individual program functions as managed ucode types, demote uc_function_t values to pointers into a uc_program_t entity - Promote uc_program_t to a managed type - Let uc_closure_t claim references to the owning program of the enclosed uc_function_t - Redefine public APIs uc_compile() and uc_vm_execute() APIs to return and expect an uc_program_t object respectively - Remove vallist indirection for function loading and let the compiler emit the function id directly when producing function construction code Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2022-01-29program: rename bytecode load/write functions, track path of executed fileJo-Philipp Wich
Extend source objects with a `runpath` field which contains the original path of the source being executed by the VM. When instantiating source objects from file paths, the `runpath` will be set to the `filename`. When instantiating source buffers using `uc_source_new_buffer()`, the runpath is initially unset. A new function `uc_source_runpath_set()` can be used to adjust the runtime path being associated with a source object. Extend bytecode loading logic to set the source buffer runtime path to the precompiled bytecode file path being loaded and executed. This is required for `sourcepath()` and relative paths in `include()` to function correctly when executing precompiled programs. Finally rename `uc_program_from_file()` and `uc_program_to_file()` to `uc_program_load()` and `uc_program_write()` respectively since the load part now operates on an `uc_source_t` input buffer instead of a plain `FILE *` handle. Adjust users of these API functions accordingly. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2022-01-18program: implement support for precompiling source filesJo-Philipp Wich
- Introduce new command line flags `-o` and `-O` to write compiled program code into the specified output file - Add support for transparently executing precompiled files, the lexical analyzing and com,pilation phase is skipped in this case Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2022-01-18source: refactor source file handlingJo-Philipp Wich
- 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>
2022-01-18compiler, vm: use a program wide constant listJo-Philipp Wich
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>
2022-01-18types: add initial infrastructure for function serializationJo-Philipp Wich
- 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>
2022-01-04vallist: store double values in a platform neutral mannerJo-Philipp Wich
Import the binary64 double packing routines from the struct module and use them to store numeric double values in a platform agnostic big endian format. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2022-01-04treewide: rework numeric value handlingJo-Philipp Wich
- 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>
2021-12-08vm: introduce value registryJo-Philipp Wich
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>
2021-12-07treewide: fix "resource" misspellingsJo-Philipp Wich
Fix various misspelling of "resource". This commit changes the exported libucode ABI. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2021-12-07treewide: fix upvalue reference type nameJo-Philipp Wich
No functional changes. Fixes: ff52440 ("treewide: consolidate typedef naming") Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2021-12-01syntax: disallow keywords in object property shorthand notationJo-Philipp Wich
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2021-11-01treewide: fix typo in exported function names and typesJo-Philipp Wich
Fix instances of misspelled "resource". This commit breaks the exported libucode ABI. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2021-10-11syntax: introduce optional chaining operatorsJo-Philipp Wich
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>
2021-09-21lib: introduce Linux 802.11 netlink bindingJo-Philipp Wich
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2021-09-15rtnl: expose IPv4 and IPv6 devconfig informationJo-Philipp Wich
# ucode -mrtnl -Rs 'printf("%.J", rtnl.request(rtnl.const.RTM_GETLINK, 0, { dev: "lo" }))' { "family": 0, "type": 772, "dev": "lo", "flags": 65609, "address": "00:00:00:00:00:00", "broadcast": "00:00:00:00:00:00", "txqlen": 1000, "mtu": 65536, "carrier": true, "linkmode": 0, "operstate": 0, "num_tx_queues": 1, "num_rx_queues": 1, "af_spec": { "inet": { "conf": { "forwarding": 1, "mc_forwarding": 0, "proxy_arp": 0, "accept_redirects": 1, "secure_redirects": 1, "send_redirects": 1, "shared_media": 1, "rp_filter": 0, "accept_source_route": 1, "bootp_relay": 0, "log_martians": 0, "tag": 0, "arpfilter": 0, "medium_id": 0, "noxfrm": 1, "nopolicy": 1, "force_igmp_version": 0, "arp_announce": 0, "arp_ignore": 0, "promote_secondaries": 0, "arp_accept": 0, "arp_notify": 0, "accept_local": 0, "src_vmark": 0, "proxy_arp_pvlan": 0, "route_localnet": 0, "igmpv2_unsolicited_report_interval": 10000, "igmpv3_unsolicited_report_interval": 1000, "ignore_routes_with_linkdown": 0, "drop_unicast_in_l2_multicast": 0, "drop_gratuitous_arp": 0, "bc_forwarding": 0 } }, "inet6": { "mode": 0, "flags": 2147483648, "conf": { "forwarding": 0, "hoplimit": 64, "mtu6": 65536, "accept_ra": 1, "accept_redirects": 1, "autoconf": 1, "dad_transmits": 1, "rtr_solicits": -1, "rtr_solicit_interval": 4000, "rtr_solicit_delay": 1000, "use_tempaddr": -1, "temp_valid_lft": 604800, "temp_prefered_lft": 86400, "regen_max_retry": 3, "max_desync_factor": 600, "max_addresses": 16, "force_mld_version": 0, "accept_ra_defrtr": 1, "accept_ra_pinfo": 1, "accept_ra_rtr_pref": 1, "rtr_probe_interval": 60000, "accept_ra_rt_info_max_plen": 0, "proxy_ndp": 0, "optimistic_dad": 0, "accept_source_route": 0, "mc_forwarding": 0, "disable_ipv6": 0, "accept_dad": -1, "force_tllao": 0, "ndisc_notify": 0, "mldv1_unsolicited_report_interval": 10000, "mldv2_unsolicited_report_interval": 1000, "suppress_frag_ndisc": 1, "accept_ra_from_local": 0, "use_optimistic": 0, "accept_ra_mtu": 1, "stable_secret": 0, "use_oif_addrs_only": 0, "accept_ra_min_hop_limit": 1, "ignore_routes_with_linkdown": 0, "drop_unicast_in_l2_multicast": 0, "drop_unsolicited_na": 0, "keep_addr_on_down": 0, "rtr_solicit_max_interval": 3600000, "seg6_enabled": 0, "seg6_require_hmac": 0, "enhanced_dad": 1, "addr_gen_mode": 0, "disable_policy": 0, "accept_ra_rt_info_min_plen": 0, "ndisc_tclass": 0, "rpl_seg_enabled": 0 } } }, "proto_down": false, "group": 0, "ifname": "lo" } Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2021-09-15lib: introduce Linux route netlink bindingJo-Philipp Wich
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2021-07-11treewide: harmonize function namingJo-Philipp Wich
- 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>