You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This is a proposal to add plugin support for Javy.
What problems does it solve?
At the moment, if someone wants to add custom JS APIs to Javy, they need to fork most of the project (javy-cli and javy-core). Ideally it would be possible to add custom JS APIs to Javy without forking anything.
We also have a problem with dynamically linked modules where import namespaces generated by the Javy CLI are rolled out before support for those import namespaces is available where they would be used. Specifically, to support using dynamically linked modules in a given runtime environment, the runtime environment needs to configure a linker with one or more Javy import namespaces (e.g., javy_quickjs_provider_v3) to load a QuickJS provider Wasm module. New releases of the Javy CLI can potentially change the import namespace used (in the future, a release could introduce a javy_quickjs_provider_v4 import namespace). However, a runtime environment using Javy would likely not be updated before the new release of the Javy CLI is available. So users using the latest Javy CLI release may create modules that are not compatible with that runtime environment.
As well, plugins should be able to specify their own import namespace because they may have their own JS APIs and the lifecycle of those APIs can be different than Javy CLI releases.
What are the changes?
The javy build subcommand will accept a new -C plugin=plugin.wasm argument. The details of what's in the plugin.wasm file will be provided below.
The -C plugin=plugin.wasm argument will be optional for the default statically linked modules. E.g., javy build -C plugin=my_plugin.wasm.
The -C plugin=plugin.wasm argument will be required for the dynamically linked modules (this is a breaking change). E.g., javy build -C dynamic -C plugin=my_plugin.wasm.
An initialize-plugin subcommand will be added to the Javy CLI. This command will need to be run to initialize a plugin before it can be used. This is intended to be run prior to distributing the plugin and not on an end user's machine. E.g., javy initialize-plugin path_to_myplugin.wasm -o=my_initialized_plugin.wasm.
Change emit-provider to emit-pluginand apply -J options to the emitted plugin. E.g., javy emit-plugin.
Possible future changes
Update emit-plugin to accept -J options if there is demand for allowing runtime configurations on the vanilla plugin.
Why these changes?
The new -C plugin option allows users to specify which plugin to use, if any. Creating a dynamically linked module will require specifying a plugin to make it much harder to accidentally generate a dynamically linked module which is incompatible with a given runtime environment. The requirement to provide a plugin will force the user to seek out a plugin as opposed to assuming the default will just work. The owner of the runtime environment can instruct their users as to where to find the plugin or provide their own tooling to download the appropriate plugin and configure Javy to use it.
Plugin module API
The plugin module is expected to be compiled as a wasm32-wasicdylib. The module must have the following exports (details provided below):
initialize_runtime() -> ()
canonical_abi_realloc(i32, i32, i32, i32) -> i32
compile_src(i32, i32) -> i32
invoke(i32, i32, i32, i32) -> ()
And the following custom section:
import_namespace containing a UTF-8 encoded string
The initialize_runtime function
This function will be responsible for adding additional APIs to the JS runtime exposed by Javy. This function will also be responsible for forwarding or modifying user-provided JS runtime configurations.
An simplified example of what an implementation could look like is:
The javy::exported_fns::user_config() returns a javy::Config representing the -J options passed on the command line and can be modified. javy::exported_fns::initialize_runtime takes the configuration and a callback for configuring an initialized runtime.
This isn't the finalized API, the exports from the Javy crate will likely look slightly different.
The import_namespace custom section
Contains a UTF-8 encoded string with the import namespace to use for the module when generating a dynamically linked module.
An example of how to configure this would be to have code that looks like:
Compiles JS source code in the byte array specified by js_src_ptr and js_src_len to QuickJS bytecode using the JS runtime initialized by initialize_runtime
Executes the bytecode in the byte array specified by bytecode_ptr and bytecode_len, if fn_name_ptr and fn_name_len are not 0, then executes the JS function with the name specified in the UTF-8 encoded string specified by fn_name_ptr and fn_name_len
No code is expected to be written by plugin developers to satisfy these APIs, they will be automatically exported from the plugin module by using the javyjavy-plugins-api crate with a feature flag enabled.
Taken together, these changes should allow the creation of plugins providing custom JS APIs and the ability to version or otherwise change the import namespace of the plugin independently of the code in this Javy repository.
The text was updated successfully, but these errors were encountered:
This is a proposal to add plugin support for Javy.
What problems does it solve?
At the moment, if someone wants to add custom JS APIs to Javy, they need to fork most of the project (
javy-cli
andjavy-core
). Ideally it would be possible to add custom JS APIs to Javy without forking anything.We also have a problem with dynamically linked modules where import namespaces generated by the Javy CLI are rolled out before support for those import namespaces is available where they would be used. Specifically, to support using dynamically linked modules in a given runtime environment, the runtime environment needs to configure a linker with one or more Javy import namespaces (e.g.,
javy_quickjs_provider_v3
) to load a QuickJS provider Wasm module. New releases of the Javy CLI can potentially change the import namespace used (in the future, a release could introduce ajavy_quickjs_provider_v4
import namespace). However, a runtime environment using Javy would likely not be updated before the new release of the Javy CLI is available. So users using the latest Javy CLI release may create modules that are not compatible with that runtime environment.As well, plugins should be able to specify their own import namespace because they may have their own JS APIs and the lifecycle of those APIs can be different than Javy CLI releases.
What are the changes?
javy build
subcommand will accept a new-C plugin=plugin.wasm
argument. The details of what's in theplugin.wasm
file will be provided below.-C plugin=plugin.wasm
argument will be optional for the default statically linked modules. E.g.,javy build -C plugin=my_plugin.wasm
.-C plugin=plugin.wasm
argument will be required for the dynamically linked modules (this is a breaking change). E.g.,javy build -C dynamic -C plugin=my_plugin.wasm
.initialize-plugin
subcommand will be added to the Javy CLI. This command will need to be run to initialize a plugin before it can be used. This is intended to be run prior to distributing the plugin and not on an end user's machine. E.g.,javy initialize-plugin path_to_myplugin.wasm -o=my_initialized_plugin.wasm
.emit-provider
toemit-plugin
and apply.-J
options to the emitted plugin. E.g.,javy emit-plugin
Possible future changes
emit-plugin
to accept-J
options if there is demand for allowing runtime configurations on the vanilla plugin.Why these changes?
The new
-C plugin
option allows users to specify which plugin to use, if any. Creating a dynamically linked module will require specifying a plugin to make it much harder to accidentally generate a dynamically linked module which is incompatible with a given runtime environment. The requirement to provide a plugin will force the user to seek out a plugin as opposed to assuming the default will just work. The owner of the runtime environment can instruct their users as to where to find the plugin or provide their own tooling to download the appropriate plugin and configure Javy to use it.Plugin module API
The plugin module is expected to be compiled as a
wasm32-wasi
cdylib
. The module must have the following exports (details provided below):initialize_runtime() -> ()
canonical_abi_realloc(i32, i32, i32, i32) -> i32
compile_src(i32, i32) -> i32
invoke(i32, i32, i32, i32) -> ()
And the following custom section:
import_namespace
containing a UTF-8 encoded stringThe
initialize_runtime
functionThis function will be responsible for adding additional APIs to the JS runtime exposed by Javy. This function will also be responsible for forwarding or modifying user-provided JS runtime configurations.
An simplified example of what an implementation could look like is:
where
JavyJson
is a copy of theJavy.JSON
implementation.The
javy::exported_fns::user_config()
returns ajavy::Config
representing the-J
options passed on the command line and can be modified.javy::exported_fns::initialize_runtime
takes the configuration and a callback for configuring an initialized runtime.This isn't the finalized API, the exports from the Javy crate will likely look slightly different.
The
import_namespace
custom sectionAn example of how to configure this would be to have code that looks like:
This will likely be simplified into a macro exported from the
javy
crate.Exports from
Javyjavy-plugins-api crateThe following functions can be exported into the plugin module from the
javy
javy-api-plugins
crate and are expected to be present:canonical_abi_realloc(original_ptr: i32, original_size: i32, alignment: i32, new_size: i32) -> ret_ptr: i32
new_size
withalignment
in the plugincompile_src(js_src_ptr: i32, js_src_len: i32) -> ret_ptr: i32
js_src_ptr
andjs_src_len
to QuickJS bytecode using the JS runtime initialized byinitialize_runtime
invoke(bytecode_ptr: i32, bytecode_len: i32, fn_name_ptr: i32, fn_name_len: i32) -> ()
bytecode_ptr
andbytecode_len
, iffn_name_ptr
andfn_name_len
are not 0, then executes the JS function with the name specified in the UTF-8 encoded string specified byfn_name_ptr
andfn_name_len
No code is expected to be written by plugin developers to satisfy these APIs, they will be automatically exported from the plugin module by using the
javy
javy-plugins-api
cratewith a feature flag enabled.Taken together, these changes should allow the creation of plugins providing custom JS APIs and the ability to version or otherwise change the import namespace of the plugin independently of the code in this Javy repository.
The text was updated successfully, but these errors were encountered: