Skip to content

Commit 399936a

Browse files
authored
Update config schema API to not use WASI (#964)
1 parent d4a605c commit 399936a

2 files changed

Lines changed: 36 additions & 23 deletions

File tree

crates/cli/src/js_config.rs

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
use anyhow::Result;
1+
use anyhow::{anyhow, Result};
22
use serde::Deserialize;
33
use std::{collections::HashMap, str};
4-
use wasmtime::{AsContextMut, Engine, Linker};
5-
use wasmtime_wasi::{pipe::MemoryOutputPipe, WasiCtxBuilder};
4+
use wasmtime::{AsContext, AsContextMut, Engine, Linker};
5+
use wasmtime_wasi::WasiCtxBuilder;
66

77
use crate::{CliPlugin, PluginKind};
88

@@ -21,18 +21,23 @@ impl ConfigSchema {
2121
let module = wasmtime::Module::new(&engine, cli_plugin.as_plugin().as_bytes())?;
2222
let mut linker = Linker::new(&engine);
2323
wasmtime_wasi::preview1::add_to_linker_sync(&mut linker, |s| s)?;
24-
let stdout = MemoryOutputPipe::new(usize::MAX);
25-
let wasi = WasiCtxBuilder::new()
26-
.inherit_stderr()
27-
.stdout(stdout.clone())
28-
.build_p1();
24+
let wasi = WasiCtxBuilder::new().inherit_stderr().build_p1();
2925
let mut store = wasmtime::Store::new(&engine, wasi);
3026
let instance = linker.instantiate(store.as_context_mut(), &module)?;
31-
instance
32-
.get_typed_func::<(), ()>(store.as_context_mut(), "config_schema")?
27+
28+
let ret_area = instance
29+
.get_typed_func::<(), i32>(store.as_context_mut(), "config-schema")?
3330
.call(store.as_context_mut(), ())?;
34-
drop(store);
35-
let config_json = stdout.try_into_inner().unwrap().to_vec();
31+
let memory = instance
32+
.get_memory(store.as_context_mut(), "memory")
33+
.ok_or_else(|| anyhow!("Missing memory export"))?;
34+
let mut buf = [0; 8];
35+
memory.read(store.as_context(), ret_area as usize, &mut buf)?;
36+
let offset = u32::from_le_bytes(buf[0..4].try_into().unwrap());
37+
let len = u32::from_le_bytes(buf[4..8].try_into().unwrap());
38+
let mut config_json = vec![0; len as usize];
39+
memory.read(store.as_context(), offset as usize, &mut config_json)?;
40+
3641
let config_schema = serde_json::from_slice::<ConfigSchema>(&config_json)?;
3742
let mut configs = Vec::with_capacity(config_schema.supported_properties.len());
3843
for config in config_schema.supported_properties {

crates/plugin/src/shared_config/mod.rs

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,19 @@
11
//! APIs and data structures for receiving runtime configuration from the Javy CLI.
22
3+
use std::cell::OnceCell;
4+
35
use anyhow::Result;
46
use javy_plugin_api::Config;
57
use serde::Deserialize;
6-
use std::io::{stdout, Write};
78

89
mod runtime_config;
910

1011
use crate::runtime_config;
1112

13+
thread_local! {
14+
static CONFIG_RET_AREA: OnceCell<[u32; 2]> = const { OnceCell::new() };
15+
}
16+
1217
runtime_config! {
1318
#[derive(Debug, Default, Deserialize)]
1419
#[serde(deny_unknown_fields, rename_all = "kebab-case")]
@@ -48,14 +53,17 @@ impl SharedConfig {
4853
}
4954
}
5055

51-
#[export_name = "config_schema"]
52-
pub fn config_schema() {
53-
stdout()
54-
.write_all(
55-
serde_json::to_string(&SharedConfig::config_schema())
56-
.unwrap()
57-
.as_bytes(),
58-
)
59-
.unwrap();
60-
stdout().flush().unwrap();
56+
#[export_name = "config-schema"]
57+
pub fn config_schema() -> *const u32 {
58+
let schema = serde_json::to_string(&SharedConfig::config_schema())
59+
.unwrap()
60+
.into_bytes();
61+
let len = schema.len();
62+
// Leak the config schema. This should be fine since the Wasm instance will
63+
// be torn down right after by the Javy CLI.
64+
let bytecode_ptr = Box::leak(schema.into_boxed_slice()).as_ptr();
65+
CONFIG_RET_AREA.with(|v| {
66+
v.set([bytecode_ptr as u32, len as u32]).unwrap();
67+
v.get().unwrap().as_ptr()
68+
})
6169
}

0 commit comments

Comments
 (0)