-
Notifications
You must be signed in to change notification settings - Fork 122
Description
This proposal is for Javy to adopt WASI preview 2 and the component model as a build target for its plugins but have the plugin initialization process output a core Wasm module. The Javy CLI will also continue to emit core Wasm modules.
What problems does it solve?
WASI preview 1 is slated for deprecation in mid-2026. We want to make sure Javy's plugin architecture is not depending on build targets that will be discontinued. We think WASI preview 2 is currently the best candidate target. wasm32-unknown-unknown
is not feasible due to rquickjs requiring a libc for compilation. When future versions of WASI build targets are released, we believe it should be straightforward for plugins to use those build targets with minimal changes.
What changes will be required?
What would be involved with updating a Javy plugin?
- Add the following WIT file in a
wit
directory adjacent to yourCargo.toml
:
package examplenamespace:my-plugin@1.0.0;
world my-javy-plugin {
export compile-src: func(src: list<u8>) -> list<u8>;
export initialize-runtime: func();
export invoke: func(bytecode: list<u8>, function: option<string>);
}
- Add
wit-bindgen
as a dependency to your plugin. - Update your plugin file to look like the following:
use javy_plugin_api::{
javy::Runtime,
javy_plugin, Config,
};
wit_bindgen::generate!({ world: "my-javy-plugin", generate_all });
fn config() -> Config {
// Set your config as before.
Config::default()
}
fn modify_runtime(runtime: Runtime) -> Runtime {
// Modify your runtime as before.
runtime
}
// This will provide implementations for all required exports.
struct Component;
// This will provide default implementations for all required exports on `Component` with `config` and `modify_runtime` being called.
javy_plugin!("my-import-namespace", Component, config, modify_runtime);
// Actually exports the functions.
export!(Component);
- Compile the plugin to
wasm32-wasip2
instead ofwasm32-wasip1
. - Initialize the plugin with
javy init-plugin ...
.
Will the Javy CLI support plugins that are components or emit components?
No, these are out-of-scope for this change. If you want to use JavaScript Wasm Components, you should consider using ComponentizeJS
.
Plugin API changes
The Javy CLI will be updated to consume plugin APIs that are defined using component exports. The component model requires export names to use kebab-casing as opposed to underscore separators with the exception of the memory reallocation function. This means the names and signatures of the functions expected to be exported by plugins by the Javy CLI will change in the following ways:
Old signature | New signature (component) | New signature (module) |
---|---|---|
compile_src: func(bytecode_ptr: u32, bytecode_len: u32) -> () |
compile-src: func(bytecode: list<u8>) -> list<u8> |
compile-src: func(u32, u32) -> u32 |
initialize_runtime: func() -> () |
initialize-runtime: func() -> () |
initialize-runtime: func() -> () |
invoke: func(bytecode_ptr: u32, bytecode_len: u32, fn_name_ptr: u32, fn_name_len: u32) -> () |
invoke: func(bytecode: list<u8>, function: option<string>) -> () |
invoke: func(u32, u32, u32, u32, u32) -> () |
canonical_abi_realloc(old_ptr: u32, old_size: u32, alignment: u32, new_size: u32) -> u32 |
cabi_realloc(old_ptr: u32, old_size: u32, alignment: u32, new_size: u32) -> u32 |
cabi_realloc(old_ptr: u32, old_size: u32, alignment: u32, new_size: u32) -> u32 |
Plugins using the existing plugin API will not work with new versions of the Javy CLI. Those plugins will need to be updated to use the new plugin API to work with new versions of the Javy CLI.
Additionally, dynamically linked modules compiled with an old plugin cannot be linked with a new plugin due to the changes to the invoke
signature. However, dynamically linked modules compiled with an old plugin can continue to be linked with that older plugin.
What will the code changes look like?
This draft PR demonstrates what I have in mind for the changes. Look at the test plugin to get an idea of the scope of the changes.