jow- / ucode

JavaScript-like language with optional templating
ISC License
90 stars 30 forks source link

Add import statement support for dynamic extensions #98

Closed jow- closed 2 years ago

jow- commented 2 years ago

Major changes:

lib: internally expose new uc_require_library() helper

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.

vm: introduce new I_DYNLOAD opcode

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.

compiler: add import statement support for dynamic extensions

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.