mirror of
https://github.com/extism/extism.git
synced 2026-01-08 21:38:13 -05:00
Update to wasmtime version with exceptions support (#880)
The [wasmtime v37 release](https://github.com/bytecodealliance/wasmtime/releases/tag/v37.0.0) "now fully implements the WebAssembly exception-handling proposal." Support for exception-handling is disabled by default, but will be made default in the future (according to the release notes). To use this new wasmtime feature, we do two things at a high level: 1. Update wasmtime dependency to version 37 2. Add a "wasmtime-exceptions" Extism feature, disabled by default. Updating to the new wasmtime dependency required some semantical changes to how the cache is configured. There is also a new `ExternType` to match on when handling invalid imports. My use case for this feature is being able to execute Lua code from Extism. In actuality, I'm running a Rust plugin, which is using [mlua](https://github.com/mlua-rs/mlua) to execute the Lua. I have it working locally with this change. Fwiw, mlua recently added [support to compile to wasi](https://github.com/mlua-rs/mlua/issues/366), which should make this all work end-to-end with no special patches if we can get this merged. This is my first time working on the Extism codebase, so please let me know if I missed anything.
This commit is contained in:
@@ -9,7 +9,7 @@ repository.workspace = true
|
||||
version.workspace = true
|
||||
|
||||
[dependencies]
|
||||
wasmtime = { version = ">= 27.0.0, < 31.0.0", default-features = false, features = [
|
||||
wasmtime = { version="37", default-features = false, features = [
|
||||
'cache',
|
||||
'gc',
|
||||
'gc-drc',
|
||||
@@ -20,8 +20,8 @@ wasmtime = { version = ">= 27.0.0, < 31.0.0", default-features = false, features
|
||||
'pooling-allocator',
|
||||
'demangle',
|
||||
] }
|
||||
wasi-common = { version = ">= 27.0.0, < 31.0.0" }
|
||||
wiggle = { version = ">= 27.0.0, < 31.0.0" }
|
||||
wasi-common = "37"
|
||||
wiggle = "37"
|
||||
anyhow = "1"
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
serde_json = "1"
|
||||
@@ -43,13 +43,15 @@ libc = "0.2"
|
||||
|
||||
[features]
|
||||
default = ["http", "register-http", "register-filesystem", "wasmtime-default-features"]
|
||||
register-http = ["ureq"] # enables wasm to be downloaded using http
|
||||
register-filesystem = [] # enables wasm to be loaded from disk
|
||||
http = ["ureq"] # enables extism_http_request
|
||||
register-http = ["ureq"] # enables wasm to be downloaded using http
|
||||
register-filesystem = [] # enables wasm to be loaded from disk
|
||||
http = ["ureq"] # enables extism_http_request
|
||||
wasmtime-exceptions = [] # enables exception-handling proposal in wasmtime (requires wasmtime gc feature)
|
||||
wasmtime-default-features = [
|
||||
'wasmtime/default',
|
||||
]
|
||||
|
||||
|
||||
[build-dependencies]
|
||||
cbindgen = { version = "0.29", default-features = false }
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
use std::{
|
||||
any::Any,
|
||||
collections::{BTreeMap, BTreeSet},
|
||||
path::PathBuf,
|
||||
sync::TryLockError,
|
||||
};
|
||||
|
||||
@@ -60,26 +61,16 @@ impl CompiledPlugin {
|
||||
.wasm_tail_call(true)
|
||||
.wasm_function_references(true)
|
||||
.wasm_gc(true);
|
||||
#[cfg(feature = "wasmtime-exceptions")]
|
||||
{
|
||||
config.wasm_exceptions(true);
|
||||
}
|
||||
|
||||
if builder.options.fuel.is_some() {
|
||||
config.consume_fuel(true);
|
||||
}
|
||||
|
||||
match &builder.options.cache_config {
|
||||
Some(None) => (),
|
||||
Some(Some(path)) => {
|
||||
config.cache_config_load(path)?;
|
||||
}
|
||||
None => {
|
||||
if let Ok(env) = std::env::var("EXTISM_CACHE_CONFIG") {
|
||||
if !env.is_empty() {
|
||||
config.cache_config_load(&env)?;
|
||||
}
|
||||
} else {
|
||||
config.cache_config_load_default()?;
|
||||
}
|
||||
}
|
||||
}
|
||||
config.cache(Self::configure_cache(&builder.options.cache_config)?);
|
||||
|
||||
let engine = Engine::new(&config)?;
|
||||
|
||||
@@ -97,6 +88,43 @@ impl CompiledPlugin {
|
||||
engine,
|
||||
})
|
||||
}
|
||||
|
||||
/// Return optional cache according to builder options.
|
||||
fn configure_cache(
|
||||
cache_opt: &Option<Option<std::path::PathBuf>>,
|
||||
) -> Result<Option<wasmtime::Cache>, Error> {
|
||||
match cache_opt {
|
||||
// Explicitly disabled
|
||||
Some(None) => Ok(None),
|
||||
|
||||
// Explicit path
|
||||
Some(Some(p)) => {
|
||||
let cache = wasmtime::Cache::from_file(Some(p.as_path()))?;
|
||||
Ok(Some(cache))
|
||||
}
|
||||
|
||||
// Unspecified, try environment, then system fallback
|
||||
None => {
|
||||
match std::env::var_os("EXTISM_CACHE_CONFIG") {
|
||||
Some(val) => {
|
||||
if val.is_empty() {
|
||||
// Disable cache if env var exists but is empty
|
||||
Ok(None)
|
||||
} else {
|
||||
let p = PathBuf::from(val);
|
||||
let cache = wasmtime::Cache::from_file(Some(p.as_path()))?;
|
||||
Ok(Some(cache))
|
||||
}
|
||||
}
|
||||
None => {
|
||||
// load cache configuration from the system default path
|
||||
let cache = wasmtime::Cache::from_file(None)?;
|
||||
Ok(Some(cache))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Plugin contains everything needed to execute a WASM function
|
||||
@@ -344,6 +372,7 @@ fn relink(
|
||||
let (kind, ty) = match import.ty() {
|
||||
ExternType::Func(t) => ("function", t.to_string()),
|
||||
ExternType::Global(t) => ("global", t.content().to_string()),
|
||||
ExternType::Tag(t) => ("tag", t.ty().to_string()),
|
||||
ExternType::Table(t) => ("table", t.element().to_string()),
|
||||
ExternType::Memory(_) => ("memory", String::new()),
|
||||
};
|
||||
|
||||
@@ -49,7 +49,7 @@ impl PoolPlugin {
|
||||
}
|
||||
|
||||
/// Access the underlying plugin
|
||||
pub fn plugin(&self) -> std::cell::RefMut<Plugin> {
|
||||
pub fn plugin(&self) -> std::cell::RefMut<'_, Plugin> {
|
||||
self.0.borrow_mut()
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user