Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix CI #712

Merged
merged 3 commits into from
Aug 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
339 changes: 0 additions & 339 deletions Cargo.lock

Large diffs are not rendered by default.

2 changes: 0 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
[workspace]
members = [
"crates/quickjs-wasm-sys",
"crates/quickjs-wasm-rs",
"crates/javy",
"crates/apis",
"crates/core",
Expand Down
10 changes: 1 addition & 9 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -49,15 +49,7 @@ test-config:

tests: test-javy test-core test-runner test-cli test-wpt test-config

fmt: fmt-quickjs-wasm-sys fmt-quickjs-wasm-rs fmt-javy fmt-apis fmt-core fmt-cli

fmt-quickjs-wasm-sys:
cargo fmt --package=quickjs-wasm-sys -- --check
cargo clippy --package=quickjs-wasm-sys --target=wasm32-wasi --all-targets -- -D warnings

fmt-quickjs-wasm-rs:
cargo fmt --package=quickjs-wasm-rs -- --check
cargo clippy --package=quickjs-wasm-rs --target=wasm32-wasi --all-targets -- -D warnings
fmt: fmt-javy fmt-apis fmt-core fmt-cli

fmt-javy:
cargo fmt --package=javy -- --check
Expand Down
24 changes: 14 additions & 10 deletions crates/cli/benches/benchmark.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use wasi_common::{
sync::WasiCtxBuilder,
WasiCtx,
};
use wasmtime::{Engine, Linker, Module, Store};
use wasmtime::{AsContextMut, Engine, Linker, Module, Store};

struct FunctionCase {
name: String,
Expand Down Expand Up @@ -84,22 +84,26 @@ impl FunctionCase {
Ok(function_case)
}

pub fn run(&self, linker: &mut Linker<WasiCtx>, mut store: &mut Store<WasiCtx>) -> Result<()> {
pub fn run(
&self,
linker: &mut Linker<WasiCtx>,
mut store: impl AsContextMut<Data = WasiCtx>,
) -> Result<()> {
let js_module = match &self.precompiled_elf_bytes {
Some(bytes) => unsafe { Module::deserialize(&self.engine, bytes) }?,
None => Module::new(&self.engine, &self.wasm_bytes)?,
};

let consumer_instance = linker.instantiate(&mut store, &js_module)?;
linker.instance(&mut store, "consumer", consumer_instance)?;
let consumer_instance = linker.instantiate(store.as_context_mut(), &js_module)?;
linker.instance(store.as_context_mut(), "consumer", consumer_instance)?;

linker
.get(&mut store, "consumer", "_start")
.get(store.as_context_mut(), "consumer", "_start")
.unwrap()
.into_func()
.unwrap()
.typed::<(), ()>(&mut store)?
.call(&mut store, ())?;
.typed::<(), ()>(store.as_context())?
.call(store.as_context_mut(), ())?;
Ok(())
}

Expand All @@ -120,8 +124,8 @@ impl FunctionCase {
"../../target/wasm32-wasi/release/javy_quickjs_provider_wizened.wasm",
))?,
)?;
let instance = linker.instantiate(&mut store, &qjs_provider)?;
linker.instance(&mut store, "javy_quickjs_provider_v2", instance)?;
let instance = linker.instantiate(store.as_context_mut(), &qjs_provider)?;
linker.instance(store.as_context_mut(), "javy_quickjs_provider_v2", instance)?;
}

Ok((linker, store))
Expand Down Expand Up @@ -169,7 +173,7 @@ pub fn criterion_benchmark(c: &mut Criterion) {
|b, f| {
b.iter_with_setup(
|| function_case.setup().unwrap(),
|(mut linker, mut store)| f.run(&mut linker, &mut store).unwrap(),
|(mut linker, mut store)| f.run(&mut linker, store.as_context_mut()).unwrap(),
)
},
);
Expand Down
47 changes: 29 additions & 18 deletions crates/cli/src/bytecode.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
use anyhow::{anyhow, Result};
use wasi_common::{sync::WasiCtxBuilder, WasiCtx};
use wasmtime::{Engine, Instance, Linker, Memory, Module, Store};
use wasmtime::{AsContextMut, Engine, Instance, Linker, Memory, Module, Store};

pub const QUICKJS_PROVIDER_MODULE: &[u8] =
include_bytes!(concat!(env!("OUT_DIR"), "/provider.wasm"));

pub fn compile_source(js_source_code: &[u8]) -> Result<Vec<u8>> {
let (mut store, instance, memory) = create_wasm_env()?;
let (js_src_ptr, js_src_len) =
copy_source_code_into_instance(js_source_code, &mut store, &instance, &memory)?;
let ret_ptr = call_compile(js_src_ptr, js_src_len, &mut store, &instance)?;
let bytecode = copy_bytecode_from_instance(ret_ptr, &mut store, &memory)?;
copy_source_code_into_instance(js_source_code, store.as_context_mut(), &instance, &memory)?;
let ret_ptr = call_compile(js_src_ptr, js_src_len, store.as_context_mut(), &instance)?;
let bytecode = copy_bytecode_from_instance(ret_ptr, store.as_context_mut(), &memory)?;
Ok(bytecode)
}

Expand All @@ -24,59 +24,70 @@ fn create_wasm_env() -> Result<(Store<WasiCtx>, Instance, Memory)> {
)?;
let wasi = WasiCtxBuilder::new().inherit_stderr().build();
let mut store = Store::new(&engine, wasi);
let instance = linker.instantiate(&mut store, &module)?;
let memory = instance.get_memory(&mut store, "memory").unwrap();
let instance = linker.instantiate(store.as_context_mut(), &module)?;
let memory = instance
.get_memory(store.as_context_mut(), "memory")
.unwrap();
Ok((store, instance, memory))
}

fn copy_source_code_into_instance(
js_source_code: &[u8],
mut store: &mut Store<WasiCtx>,
mut store: impl AsContextMut,
instance: &Instance,
memory: &Memory,
) -> Result<(u32, u32)> {
let realloc_fn = instance
.get_typed_func::<(u32, u32, u32, u32), u32>(&mut store, "canonical_abi_realloc")?;
let realloc_fn = instance.get_typed_func::<(u32, u32, u32, u32), u32>(
store.as_context_mut(),
"canonical_abi_realloc",
)?;
let js_src_len = js_source_code.len().try_into()?;

let original_ptr = 0;
let original_size = 0;
let alignment = 1;
let size = js_src_len;
let js_source_ptr =
realloc_fn.call(&mut store, (original_ptr, original_size, alignment, size))?;
let js_source_ptr = realloc_fn.call(
store.as_context_mut(),
(original_ptr, original_size, alignment, size),
)?;

memory.write(&mut store, js_source_ptr.try_into()?, js_source_code)?;
memory.write(
store.as_context_mut(),
js_source_ptr.try_into()?,
js_source_code,
)?;

Ok((js_source_ptr, js_src_len))
}

fn call_compile(
js_src_ptr: u32,
js_src_len: u32,
mut store: &mut Store<WasiCtx>,
mut store: impl AsContextMut,
instance: &Instance,
) -> Result<u32> {
let compile_src_fn = instance.get_typed_func::<(u32, u32), u32>(&mut store, "compile_src")?;
let compile_src_fn =
instance.get_typed_func::<(u32, u32), u32>(store.as_context_mut(), "compile_src")?;
let ret_ptr = compile_src_fn
.call(&mut store, (js_src_ptr, js_src_len))
.call(store.as_context_mut(), (js_src_ptr, js_src_len))
.map_err(|_| anyhow!("JS compilation failed"))?;
Ok(ret_ptr)
}

fn copy_bytecode_from_instance(
ret_ptr: u32,
mut store: &mut Store<WasiCtx>,
mut store: impl AsContextMut,
memory: &Memory,
) -> Result<Vec<u8>> {
let mut ret_buffer = [0; 8];
memory.read(&mut store, ret_ptr.try_into()?, &mut ret_buffer)?;
memory.read(store.as_context_mut(), ret_ptr.try_into()?, &mut ret_buffer)?;

let bytecode_ptr = u32::from_le_bytes(ret_buffer[0..4].try_into()?);
let bytecode_len = u32::from_le_bytes(ret_buffer[4..8].try_into()?);

let mut bytecode = vec![0; bytecode_len.try_into()?];
memory.read(&mut store, bytecode_ptr.try_into()?, &mut bytecode)?;
memory.read(store.as_context(), bytecode_ptr.try_into()?, &mut bytecode)?;

Ok(bytecode)
}
81 changes: 56 additions & 25 deletions crates/cli/tests/dylib_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use anyhow::Result;
use std::boxed::Box;
use std::str;
use wasi_common::{pipe::WritePipe, sync::WasiCtxBuilder, WasiCtx, WasiFile};
use wasmtime::{Engine, Instance, Linker, Store};
use wasmtime::{AsContextMut, Engine, Instance, Linker, Store};

mod common;

Expand Down Expand Up @@ -49,9 +49,10 @@ fn run_js_src<T: WasiFile + Clone + 'static>(js_src: &str, stderr: &T) -> Result
let (instance, mut store) = create_wasm_env(stderr)?;

let eval_bytecode_func =
instance.get_typed_func::<(u32, u32), ()>(&mut store, "eval_bytecode")?;
let (bytecode_ptr, bytecode_len) = compile_src(js_src.as_bytes(), &instance, &mut store)?;
eval_bytecode_func.call(&mut store, (bytecode_ptr, bytecode_len))?;
instance.get_typed_func::<(u32, u32), ()>(store.as_context_mut(), "eval_bytecode")?;
let (bytecode_ptr, bytecode_len) =
compile_src(js_src.as_bytes(), &instance, store.as_context_mut())?;
eval_bytecode_func.call(store.as_context_mut(), (bytecode_ptr, bytecode_len))?;
Ok(())
}

Expand All @@ -62,11 +63,14 @@ fn run_invoke<T: WasiFile + Clone + 'static>(
) -> Result<()> {
let (instance, mut store) = create_wasm_env(stderr)?;

let invoke_func = instance.get_typed_func::<(u32, u32, u32, u32), ()>(&mut store, "invoke")?;
let (bytecode_ptr, bytecode_len) = compile_src(js_src.as_bytes(), &instance, &mut store)?;
let (fn_name_ptr, fn_name_len) = copy_func_name(fn_to_invoke, &instance, &mut store)?;
let invoke_func =
instance.get_typed_func::<(u32, u32, u32, u32), ()>(store.as_context_mut(), "invoke")?;
let (bytecode_ptr, bytecode_len) =
compile_src(js_src.as_bytes(), &instance, store.as_context_mut())?;
let (fn_name_ptr, fn_name_len) =
copy_func_name(fn_to_invoke, &instance, store.as_context_mut())?;
invoke_func.call(
&mut store,
store.as_context_mut(),
(bytecode_ptr, bytecode_len, fn_name_ptr, fn_name_len),
)?;
Ok(())
Expand All @@ -84,25 +88,36 @@ fn create_wasm_env<T: WasiFile + Clone + 'static>(
let module = common::create_quickjs_provider_module(&engine)?;

let mut store = Store::new(&engine, wasi);
let instance = linker.instantiate(&mut store, &module)?;
let instance = linker.instantiate(store.as_context_mut(), &module)?;

Ok((instance, store))
}

fn compile_src(
js_src: &[u8],
instance: &Instance,
mut store: &mut Store<WasiCtx>,
mut store: impl AsContextMut,
) -> Result<(u32, u32)> {
let memory = instance.get_memory(&mut store, "memory").unwrap();
let compile_src_func = instance.get_typed_func::<(u32, u32), u32>(&mut store, "compile_src")?;

let js_src_ptr = allocate_memory(instance, store, 1, js_src.len().try_into()?)?;
memory.write(&mut store, js_src_ptr.try_into()?, js_src)?;
let memory = instance
.get_memory(store.as_context_mut(), "memory")
.unwrap();
let compile_src_func =
instance.get_typed_func::<(u32, u32), u32>(store.as_context_mut(), "compile_src")?;

let js_src_ptr = allocate_memory(
instance,
store.as_context_mut(),
1,
js_src.len().try_into()?,
)?;
memory.write(store.as_context_mut(), js_src_ptr.try_into()?, js_src)?;

let ret_ptr = compile_src_func.call(&mut store, (js_src_ptr, js_src.len().try_into()?))?;
let ret_ptr = compile_src_func.call(
store.as_context_mut(),
(js_src_ptr, js_src.len().try_into()?),
)?;
let mut ret_buffer = [0; 8];
memory.read(&mut store, ret_ptr.try_into()?, &mut ret_buffer)?;
memory.read(store.as_context(), ret_ptr.try_into()?, &mut ret_buffer)?;
let bytecode_ptr = u32::from_le_bytes(ret_buffer[0..4].try_into()?);
let bytecode_len = u32::from_le_bytes(ret_buffer[4..8].try_into()?);

Expand All @@ -112,27 +127,43 @@ fn compile_src(
fn copy_func_name(
fn_name: &str,
instance: &Instance,
mut store: &mut Store<WasiCtx>,
mut store: impl AsContextMut,
) -> Result<(u32, u32)> {
let memory = instance.get_memory(&mut store, "memory").unwrap();
let memory = instance
.get_memory(store.as_context_mut(), "memory")
.unwrap();
let fn_name_bytes = fn_name.as_bytes();
let fn_name_ptr = allocate_memory(instance, store, 1, fn_name_bytes.len().try_into()?)?;
memory.write(&mut store, fn_name_ptr.try_into()?, fn_name_bytes)?;
let fn_name_ptr = allocate_memory(
instance,
store.as_context_mut(),
1,
fn_name_bytes.len().try_into()?,
)?;
memory.write(
store.as_context_mut(),
fn_name_ptr.try_into()?,
fn_name_bytes,
)?;

Ok((fn_name_ptr, fn_name_bytes.len().try_into()?))
}

fn allocate_memory(
instance: &Instance,
mut store: &mut Store<WasiCtx>,
mut store: impl AsContextMut,
alignment: u32,
new_size: u32,
) -> Result<u32> {
let realloc_func = instance
.get_typed_func::<(u32, u32, u32, u32), u32>(&mut store, "canonical_abi_realloc")?;
let realloc_func = instance.get_typed_func::<(u32, u32, u32, u32), u32>(
store.as_context_mut(),
"canonical_abi_realloc",
)?;
let orig_ptr = 0;
let orig_size = 0;
realloc_func
.call(&mut store, (orig_ptr, orig_size, alignment, new_size))
.call(
store.as_context_mut(),
(orig_ptr, orig_size, alignment, new_size),
)
.map_err(Into::into)
}
13 changes: 7 additions & 6 deletions crates/cli/tests/dynamic_linking_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use uuid::Uuid;
use wasi_common::pipe::{ReadPipe, WritePipe};
use wasi_common::sync::WasiCtxBuilder;
use wasi_common::WasiCtx;
use wasmtime::{Config, Engine, ExternType, Linker, Module, Store};
use wasmtime::{AsContextMut, Config, Engine, ExternType, Linker, Module, Store};

mod common;

Expand Down Expand Up @@ -223,15 +223,16 @@ fn invoke_fn_on_generated_module(
let quickjs_provider_module = common::create_quickjs_provider_module(&engine)?;
let js_module = Module::from_binary(&engine, &js_wasm)?;

let quickjs_provider_instance = linker.instantiate(&mut store, &quickjs_provider_module)?;
let quickjs_provider_instance =
linker.instantiate(store.as_context_mut(), &quickjs_provider_module)?;
linker.instance(
&mut store,
store.as_context_mut(),
"javy_quickjs_provider_v2",
quickjs_provider_instance,
)?;
let js_instance = linker.instantiate(&mut store, &js_module)?;
let func = js_instance.get_typed_func::<(), ()>(&mut store, func)?;
func.call(&mut store, ())?;
let js_instance = linker.instantiate(store.as_context_mut(), &js_module)?;
let func = js_instance.get_typed_func::<(), ()>(store.as_context_mut(), func)?;
func.call(store.as_context_mut(), ())?;

drop(store); // Need to drop store to access contents of stderr.
let log_output = stderr.try_into_inner().unwrap().into_inner();
Expand Down
4 changes: 2 additions & 2 deletions crates/javy/src/alloc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ const ZERO_SIZE_ALLOCATION_PTR: *mut u8 = 1 as _;
///
/// 1. Allocate memory of new_size with alignment.
/// 2. If original_ptr != 0.
/// a. copy min(new_size, original_size) bytes from original_ptr to new memory.
/// b. de-allocate original_ptr.
/// a. copy min(new_size, original_size) bytes from original_ptr to new memory.
/// b. de-allocate original_ptr.
/// 3. Return new memory ptr.
///
/// # Safety
Expand Down
2 changes: 2 additions & 0 deletions crates/javy/tests/misc.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
#[cfg(feature = "json")]
use anyhow::Result;
#[cfg(feature = "json")]
use javy::{quickjs::context::EvalOptions, Config, Runtime};

#[cfg(feature = "json")]
Expand Down
Loading