summaryrefslogtreecommitdiffhomepage
path: root/lib.c
AgeCommit message (Collapse)Author
2021-07-11vm: move global scope allocation into uc_vm_init()Jo-Philipp Wich
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2021-07-11vm: add getter and setter for vm globals scopeJo-Philipp Wich
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2021-07-11lib: rename uc_add_proto_functions() to uc_add_functions()Jo-Philipp Wich
The naming is an artifact from before the introduction of the new type system. In the current code, there is nothing special about prototypes, they're simple object values. Also introduce a new singular uc_add_function() convenience macro while we're at it. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2021-07-11lib: expose stdlib function arrayJo-Philipp Wich
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2021-07-11treewide: move ressource type registry into vm instanceJo-Philipp Wich
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2021-07-07lib: fix refcount imbalance in uc_require_path()Jo-Philipp Wich
Ensure to increase the refcount of the module scope value when caching it in the global module registry to avoid a double free on VM teardown. Fixes: 96f140b ("lib, vm: ensure that require() compiles modules only once") Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2021-07-07lib, vm: ensure that require() compiles modules only onceJo-Philipp Wich
Cache the result of a successful require operation in a global.modules object and return the cached value for subsequent require calls on the same module name. This ensures that a given module is only compiled and executed once, regardless of how many times it is used. A reload of the module can be forced by deleting the corresponding key in the global module table. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2021-06-08treewide: let uc_cmp() use instruction instead of token numbersJo-Philipp Wich
This allows us to drop some token->instruction mapping case switches in the VM. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2021-06-08lib: implement b64enc() and b64dec() functionsJo-Philipp Wich
The new functions allow encoding and decoding base64 values respectively. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2021-06-07lib: only consider context of calling function for callbacksJo-Philipp Wich
Do not walk up the entire call stack but specifically use the context of the callframe calling the C function. Fixes: 3e893e6 ("lib: pass-through "this" context to library function callbacks") Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2021-06-07lib: implement min() and max() functionsJo-Philipp Wich
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2021-06-07lib: pass-through "this" context to library function callbacksJo-Philipp Wich
Ensure that callbacks invoked by filter(), map(), sort() and replace() inherit the "this" context that invoked the respective C function. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2021-06-04lib: implement `sourcepath()` functionJo-Philipp Wich
The sourcepath() function allows querying the filesystem path of the source file currently being executed by ucode. The optional depth argument can be used to walk up the include stack to determine the path of the file that included the current file, the path of the parent file of the parent file and so on. By specifying a truish value as second argument, only the directory portion of the source file path is returned. This is useful to e.g. discover ressources relative to the current source file directory. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2021-06-02lib: fix negative uc_index() return value on 32bit systemsJo-Philipp Wich
The numeric return value was incorrectly stored in an unsigned size_t variable which got later wrapped in an ucode signed 64bit integer value. This worked by accident on 64bit systems since (int64_t)(size_t)(-1) == -1, but it failed on 32bit ones where (int64_t)(size_t)(-1) yields 4294967295 due to the different sizes of the size_t and int64_t types. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2021-05-25syntax: drop Infinity and NaN keywordsJo-Philipp Wich
Turn the Infinity and NaN keywords into global properties. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2021-05-25lib: rename uc_lib_init() to uc_load_stdlib()Jo-Philipp Wich
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2021-05-25main, lib: move allocation of globals object into lib functionJo-Philipp Wich
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2021-05-18syntax: implement `delete` as proper operatorJo-Philipp Wich
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>
2021-05-18lib: implement wildcard() functionJo-Philipp Wich
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2021-05-11lib: implement regexp(), a function to construct regexp instances at runtimeJo-Philipp Wich
Provide a new ucode function regexp() which allows constructing regular expression instances from separate source and flag strings. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2021-05-10lib: implement render(), an include variant capturing output in a stringJo-Philipp Wich
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2021-05-10vm: implement mechanism to change output file descriptorJo-Philipp Wich
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2021-05-07lib: fix uc_sort()Jo-Philipp Wich
The internally used qsort(3) expects [-n, 0, n] return values from the comparator function instead of a true/false value to denote lower than or equal results. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2021-05-04lib: implement assert()Jo-Philipp Wich
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2021-05-04lib: add support for pretty printing JSON to printf() and sprintf()Jo-Philipp Wich
Honour precision specifiers when parsing `J` format strings to enable or disable JSON pretty printing. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2021-05-04lib: gracefully handle truncated format strings in uc_printf_common()Jo-Philipp Wich
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2021-04-29lib: fix reporting source context lines at EOFJo-Philipp Wich
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2021-04-27lib: fix uc_split() quirksJo-Philipp Wich
- Ensure that split by string produces an initial empty string in the result array when the string to split starts with the split substring - Ensure that split by string produces a trailing empty string in the result array when the string to split ends with the split substring Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2021-04-27treewide: ISO C / pedantic complianceJo-Philipp Wich
- 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>
2021-04-26treewide: address various sign-compare warningsJo-Philipp Wich
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2021-04-26lib: uc_system(): fix invalid free() of non-heap memoryJo-Philipp Wich
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2021-04-25treewide: rework internal data type systemJo-Philipp Wich
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>
2021-04-24treewide: fix issues reported by clang code analyzerJo-Philipp Wich
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2021-04-21lib: implement sleep(ms) functionJo-Philipp Wich
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2021-04-01lib: allow parsing non-array, non-object value in json()Jo-Philipp Wich
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2021-03-25lib: prevent use-after-free after uc_shift()Jo-Philipp Wich
Make sure to increase the refcount of items being moved since the subsequent put operation will decrease it, prematurely freeing moved items which will lead to use-after-free errors later on. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2021-03-24lib: fix value refcount of uc_unshift() return valueJo-Philipp Wich
The ref count of the unshifted value returned by uc_unshift() must be increased in order to prevent a subsequent double free within the VM when the value eventually goes out of scope. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2021-03-23lib: fix passing uninitialized memory to sigprocmask()Jo-Philipp Wich
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2021-03-22lib: use execvp() in system()Jo-Philipp Wich
Use execvp() instead of execv() to lookup the specified executable in $PATH. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2021-03-09lib: prevent possible use-after-free in uc_pop()Jo-Philipp Wich
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2021-03-08lib: retain prototype when passing scopes to include()Jo-Philipp Wich
Change uc_include() to retain the prototype of the given scope object when processing includes. Also change the default behaviour to register the current VM scope as prototype on the passed scope object so that included code has access to functions such as length(), print() etc. by default. To actually sandbox the included code, the new `proto()` function can be used to create a scope object with an empty prototype: `include(..., proto({ ... }, {}))` Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2021-03-08lib: use uc_prototype_lookup() to obain search path property valueJo-Philipp Wich
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2021-03-08lib: introduce new proto() ucode functionJo-Philipp Wich
The proto() function allows getting and setting the prototype value of array or object values, which is useful to build object instances. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2021-02-17treewide: rewrite ucode interpreterJo-Philipp Wich
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>
2020-12-06treewide: prevent stale pointer access in opcode handlersJo-Philipp Wich
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>
2020-11-19treewide: rebrand to ucodeJo-Philipp Wich
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2020-11-16lib: optimize length() for objectsJo-Philipp Wich
Instead of counting the keys individually, use the existing json_object_object_length() function. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2020-11-16lib: extend length() to handle objectsJo-Philipp Wich
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2020-11-16lib: extend ord() to allow reading byte values at arbitrary indexesJo-Philipp Wich
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2020-11-16lib: add system() functionJo-Philipp Wich
Signed-off-by: Jo-Philipp Wich <jo@mein.io>