mirror of
https://github.com/zed-industries/zed.git
synced 2024-12-28 03:25:59 +00:00
Fix issue with host function binding
This commit is contained in:
parent
96c2559d2c
commit
7266dff537
2 changed files with 39 additions and 52 deletions
|
@ -72,59 +72,55 @@ pub struct Wasi {
|
||||||
pub type HostFunction = Box<dyn IntoFunc<WasiCtx, (u32, u32), u32>>;
|
pub type HostFunction = Box<dyn IntoFunc<WasiCtx, (u32, u32), u32>>;
|
||||||
|
|
||||||
pub struct WasiPluginBuilder {
|
pub struct WasiPluginBuilder {
|
||||||
host_functions: HashMap<String, Box<dyn Fn(&str, &mut Linker<WasiCtx>) -> Result<(), Error>>>,
|
// host_functions: HashMap<String, Box<dyn Fn(&str, &mut Linker<WasiCtx>) -> Result<(), Error>>>,
|
||||||
wasi_ctx_builder: WasiCtxBuilder,
|
wasi_ctx: WasiCtx,
|
||||||
|
engine: Engine,
|
||||||
|
linker: Linker<WasiCtx>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WasiPluginBuilder {
|
impl WasiPluginBuilder {
|
||||||
pub fn new() -> Self {
|
pub fn new(wasi_ctx: WasiCtx) -> Result<Self, Error> {
|
||||||
WasiPluginBuilder {
|
let mut config = Config::default();
|
||||||
host_functions: HashMap::new(),
|
config.async_support(true);
|
||||||
wasi_ctx_builder: WasiCtxBuilder::new(),
|
let engine = Engine::new(&config)?;
|
||||||
}
|
let mut linker = Linker::new(&engine);
|
||||||
|
|
||||||
|
Ok(WasiPluginBuilder {
|
||||||
|
// host_functions: HashMap::new(),
|
||||||
|
wasi_ctx,
|
||||||
|
engine,
|
||||||
|
linker,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_with_default_ctx() -> WasiPluginBuilder {
|
pub fn new_with_default_ctx() -> Result<Self, Error> {
|
||||||
let mut this = Self::new();
|
let wasi_ctx = WasiCtxBuilder::new()
|
||||||
this.wasi_ctx_builder = this.wasi_ctx_builder.inherit_stdin().inherit_stderr();
|
.inherit_stdin()
|
||||||
this
|
.inherit_stderr()
|
||||||
|
.build();
|
||||||
|
Self::new(wasi_ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn host_function<A: Serialize, R: DeserializeOwned>(
|
pub fn host_function<A: Serialize, R: DeserializeOwned>(
|
||||||
mut self,
|
mut self,
|
||||||
name: &str,
|
name: &str,
|
||||||
function: &dyn Fn(A) -> R + Send + Sync + 'static,
|
function: impl Fn(A) -> R + Send + Sync + 'static,
|
||||||
) -> Self {
|
) -> Result<Self, Error> {
|
||||||
let name = name.to_string();
|
self.linker
|
||||||
self.host_functions.insert(
|
.func_wrap("env", name, move |ptr: u32, len: u32| {
|
||||||
name,
|
// TODO: insert serialization code
|
||||||
Box::new(move |name: &str, linker: &mut Linker<WasiCtx>| {
|
|
||||||
linker.func_wrap("env", name, |ptr: u32, len: u32| {
|
|
||||||
function(todo!());
|
function(todo!());
|
||||||
7u32
|
7u32
|
||||||
})?;
|
})?;
|
||||||
Ok(())
|
Ok(self)
|
||||||
}),
|
|
||||||
);
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn wasi_ctx(mut self, config: impl FnOnce(WasiCtxBuilder) -> WasiCtxBuilder) -> Self {
|
|
||||||
self.wasi_ctx_builder = config(self.wasi_ctx_builder);
|
|
||||||
self
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn init<T: AsRef<[u8]>>(self, module: T) -> Result<Wasi, Error> {
|
pub async fn init<T: AsRef<[u8]>>(self, module: T) -> Result<Wasi, Error> {
|
||||||
let plugin = WasiPlugin {
|
Wasi::init(module.as_ref().to_vec(), self).await
|
||||||
module: module.as_ref().to_vec(),
|
|
||||||
wasi_ctx: self.wasi_ctx_builder.build(),
|
|
||||||
host_functions: self.host_functions,
|
|
||||||
};
|
|
||||||
|
|
||||||
Wasi::init(plugin).await
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: remove
|
||||||
/// Represents a to-be-initialized plugin.
|
/// Represents a to-be-initialized plugin.
|
||||||
/// Please use [`WasiPluginBuilder`], don't use this directly.
|
/// Please use [`WasiPluginBuilder`], don't use this directly.
|
||||||
pub struct WasiPlugin {
|
pub struct WasiPlugin {
|
||||||
|
@ -154,26 +150,17 @@ impl Wasi {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Wasi {
|
impl Wasi {
|
||||||
async fn init(plugin: WasiPlugin) -> Result<Self, Error> {
|
async fn init(module: Vec<u8>, plugin: WasiPluginBuilder) -> Result<Self, Error> {
|
||||||
let mut config = Config::default();
|
let engine = plugin.engine;
|
||||||
config.async_support(true);
|
let mut linker = plugin.linker;
|
||||||
let engine = Engine::new(&config)?;
|
|
||||||
let mut linker = Linker::new(&engine);
|
|
||||||
|
|
||||||
for (name, add_to_linker) in plugin.host_functions.into_iter() {
|
|
||||||
add_to_linker(&name, &mut linker)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
linker
|
|
||||||
.func_wrap("env", "__command", |x: u32, y: u32| x + y)
|
|
||||||
.unwrap();
|
|
||||||
linker.func_wrap("env", "__hello", |x: u32| x * 2).unwrap();
|
linker.func_wrap("env", "__hello", |x: u32| x * 2).unwrap();
|
||||||
linker.func_wrap("env", "__bye", |x: u32| x / 2).unwrap();
|
linker.func_wrap("env", "__bye", |x: u32| x / 2).unwrap();
|
||||||
|
|
||||||
wasmtime_wasi::add_to_linker(&mut linker, |s| s)?;
|
wasmtime_wasi::add_to_linker(&mut linker, |s| s)?;
|
||||||
|
|
||||||
let mut store: Store<_> = Store::new(&engine, plugin.wasi_ctx);
|
let mut store: Store<_> = Store::new(&engine, plugin.wasi_ctx);
|
||||||
let module = Module::new(&engine, plugin.module)?;
|
let module = Module::new(&engine, module)?;
|
||||||
|
|
||||||
linker.module_async(&mut store, "", &module).await?;
|
linker.module_async(&mut store, "", &module).await?;
|
||||||
let instance = linker.instantiate_async(&mut store, &module).await?;
|
let instance = linker.instantiate_async(&mut store, &module).await?;
|
||||||
|
|
|
@ -13,12 +13,12 @@ use std::{any::Any, path::PathBuf, sync::Arc};
|
||||||
use util::{ResultExt, TryFutureExt};
|
use util::{ResultExt, TryFutureExt};
|
||||||
|
|
||||||
pub async fn new_json(executor: Arc<Background>) -> Result<PluginLspAdapter> {
|
pub async fn new_json(executor: Arc<Background>) -> Result<PluginLspAdapter> {
|
||||||
let plugin = WasiPluginBuilder::new_with_default_ctx()
|
let plugin = WasiPluginBuilder::new_with_default_ctx()?
|
||||||
.host_function("command", |command: String| {
|
.host_function("command", |command: String| {
|
||||||
// TODO: actual thing
|
// TODO: actual thing
|
||||||
std::process::Command::new(command).output().unwrap();
|
std::process::Command::new(command).output().unwrap();
|
||||||
Some("Hello".to_string())
|
Some("Hello".to_string())
|
||||||
})
|
})?
|
||||||
.init(include_bytes!("../../../../plugins/bin/json_language.wasm"))
|
.init(include_bytes!("../../../../plugins/bin/json_language.wasm"))
|
||||||
.await?;
|
.await?;
|
||||||
PluginLspAdapter::new(plugin, executor).await
|
PluginLspAdapter::new(plugin, executor).await
|
||||||
|
|
Loading…
Reference in a new issue