Skip to content

Commit

Permalink
Merge #1636
Browse files Browse the repository at this point in the history
1636: feat(c-api) Implement `wasm_module_validate` r=Hywan a=Hywan

This PR implements `wasm_module_validate`.

It returns a bool, but it populates the error handler too. I took the liberty to update the `c_try!` macro to return any kind of value, so that it is generic over the returned type of the function using `c_try!`.

Co-authored-by: Ivan Enderlin <[email protected]>
  • Loading branch information
bors[bot] and Hywan authored Oct 5, 2020
2 parents 1de0606 + 3edcc89 commit 205318d
Show file tree
Hide file tree
Showing 8 changed files with 54 additions and 60 deletions.
21 changes: 9 additions & 12 deletions lib/c-api/src/wasm_c_api/externals/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,8 @@ use super::super::types::{wasm_functype_t, wasm_valkind_enum};
use super::super::value::{wasm_val_inner, wasm_val_t};
use std::convert::TryInto;
use std::ffi::c_void;
use std::ptr::NonNull;
use std::sync::Arc;
use wasmer::{Function, Instance, RuntimeError, Store, Val};
use wasmer::{Function, Instance, RuntimeError, Val};

#[allow(non_camel_case_types)]
pub struct wasm_func_t {
Expand All @@ -31,13 +30,11 @@ pub type wasm_env_finalizer_t = unsafe extern "C" fn(c_void);

#[no_mangle]
pub unsafe extern "C" fn wasm_func_new(
store: Option<NonNull<wasm_store_t>>,
store: &wasm_store_t,
ft: &wasm_functype_t,
callback: wasm_func_callback_t,
) -> Option<Box<wasm_func_t>> {
// TODO: handle null pointers?
let store_ptr = store?.cast::<Store>();
let store = store_ptr.as_ref();
let func_sig = ft.sig();
let num_rets = func_sig.results().len();
let inner_callback = move |args: &[Val]| -> Result<Vec<Val>, RuntimeError> {
Expand Down Expand Up @@ -68,24 +65,23 @@ pub unsafe extern "C" fn wasm_func_new(
.expect("Result conversion failed");
Ok(processed_results)
};
let f = Function::new(store, &func_sig, inner_callback);
let function = Function::new(&store.inner, &func_sig, inner_callback);

Some(Box::new(wasm_func_t {
instance: None,
inner: f,
inner: function,
}))
}

#[no_mangle]
pub unsafe extern "C" fn wasm_func_new_with_env(
store: Option<NonNull<wasm_store_t>>,
store: &wasm_store_t,
ft: &wasm_functype_t,
callback: wasm_func_callback_with_env_t,
env: *mut c_void,
finalizer: wasm_env_finalizer_t,
) -> Option<Box<wasm_func_t>> {
// TODO: handle null pointers?
let store_ptr = store?.cast::<Store>();
let store = store_ptr.as_ref();
let func_sig = ft.sig();
let num_rets = func_sig.results().len();
let inner_callback =
Expand Down Expand Up @@ -114,10 +110,11 @@ pub unsafe extern "C" fn wasm_func_new_with_env(
.expect("Result conversion failed");
Ok(processed_results)
};
let f = Function::new_with_env(store, &func_sig, env, inner_callback);
let function = Function::new_with_env(&store.inner, &func_sig, env, inner_callback);

Some(Box::new(wasm_func_t {
instance: None,
inner: f,
inner: function,
}))
}

Expand Down
8 changes: 3 additions & 5 deletions lib/c-api/src/wasm_c_api/externals/global.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@ use super::super::store::wasm_store_t;
use super::super::types::wasm_globaltype_t;
use super::super::value::wasm_val_t;
use std::convert::TryInto;
use std::ptr::NonNull;
use wasmer::{Global, Store, Val};
use wasmer::{Global, Val};

#[allow(non_camel_case_types)]
pub struct wasm_global_t {
Expand All @@ -13,14 +12,13 @@ pub struct wasm_global_t {

#[no_mangle]
pub unsafe extern "C" fn wasm_global_new(
store_ptr: Option<NonNull<wasm_store_t>>,
store: &wasm_store_t,
gt: &wasm_globaltype_t,
val: &wasm_val_t,
) -> Option<Box<wasm_global_t>> {
let gt = gt.as_globaltype();
let wasm_val = val.try_into().ok()?;
let store_ptr: NonNull<Store> = store_ptr?.cast::<Store>();
let store = store_ptr.as_ref();
let store = &store.inner;
let global = if gt.mutability.is_mutable() {
Global::new_mut(store, wasm_val)
} else {
Expand Down
9 changes: 3 additions & 6 deletions lib/c-api/src/wasm_c_api/externals/memory.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
use super::super::store::wasm_store_t;
use super::super::types::wasm_memorytype_t;
use std::mem;
use std::ptr::NonNull;
use wasmer::{Memory, Pages, Store};
use wasmer::{Memory, Pages};

#[allow(non_camel_case_types)]
pub struct wasm_memory_t {
Expand All @@ -12,14 +11,12 @@ pub struct wasm_memory_t {

#[no_mangle]
pub unsafe extern "C" fn wasm_memory_new(
store_ptr: Option<NonNull<wasm_store_t>>,
store: &wasm_store_t,
mt: &wasm_memorytype_t,
) -> Option<Box<wasm_memory_t>> {
let md = mt.as_memorytype().clone();
let store_ptr: NonNull<Store> = store_ptr?.cast::<Store>();
let store = store_ptr.as_ref();
let memory = c_try!(Memory::new(&store.inner, md));

let memory = c_try!(Memory::new(store, md));
Some(Box::new(wasm_memory_t { inner: memory }))
}

Expand Down
10 changes: 3 additions & 7 deletions lib/c-api/src/wasm_c_api/externals/table.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use super::super::store::wasm_store_t;
use super::super::types::{wasm_ref_t, wasm_table_size_t, wasm_tabletype_t};
use std::ptr::NonNull;
use wasmer::{Store, Table};
use wasmer::Table;

#[allow(non_camel_case_types)]
pub struct wasm_table_t {
Expand All @@ -11,17 +10,14 @@ pub struct wasm_table_t {

#[no_mangle]
pub unsafe extern "C" fn wasm_table_new(
store_ptr: Option<NonNull<wasm_store_t>>,
store: &wasm_store_t,
tt: &wasm_tabletype_t,
init: *const wasm_ref_t,
) -> Option<Box<wasm_table_t>> {
let tt = tt.as_tabletype().clone();
let store_ptr: NonNull<Store> = store_ptr?.cast::<Store>();
let store = store_ptr.as_ref();

let init_val = todo!("get val from init somehow");
let table = c_try!(Table::new(&store.inner, tt, init_val));

let table = c_try!(Table::new(store, tt, init_val));
Some(Box::new(wasm_table_t { inner: table }))
}

Expand Down
3 changes: 1 addition & 2 deletions lib/c-api/src/wasm_c_api/instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ use super::store::wasm_store_t;
use super::trap::wasm_trap_t;
use crate::ordered_resolver::OrderedResolver;
use std::mem;
use std::ptr::NonNull;
use std::sync::Arc;
use wasmer::{Extern, Instance};

Expand Down Expand Up @@ -52,7 +51,7 @@ unsafe fn argument_import_iter(

#[no_mangle]
pub unsafe extern "C" fn wasm_instance_new(
store: Option<NonNull<wasm_store_t>>,
_store: &wasm_store_t,
module: &wasm_module_t,
imports: *const *const wasm_extern_t,
// own
Expand Down
34 changes: 24 additions & 10 deletions lib/c-api/src/wasm_c_api/module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@ use super::types::{
wasm_byte_vec_t, wasm_exporttype_t, wasm_exporttype_vec_t, wasm_importtype_t,
wasm_importtype_vec_t,
};
use crate::error::update_last_error;
use std::ptr::NonNull;
use std::slice;
use std::sync::Arc;
use wasmer::{Module, Store};
use wasmer::Module;

#[allow(non_camel_case_types)]
pub struct wasm_module_t {
Expand All @@ -15,14 +16,12 @@ pub struct wasm_module_t {

#[no_mangle]
pub unsafe extern "C" fn wasm_module_new(
store_ptr: Option<NonNull<wasm_store_t>>,
store: &wasm_store_t,
bytes: &wasm_byte_vec_t,
) -> Option<Box<wasm_module_t>> {
// TODO: review lifetime of byte slice
let wasm_byte_slice: &[u8] = slice::from_raw_parts_mut(bytes.data, bytes.size);
let store_ptr: NonNull<Store> = store_ptr?.cast::<Store>();
let store = store_ptr.as_ref();
let module = c_try!(Module::from_binary(store, wasm_byte_slice));
let module = c_try!(Module::from_binary(&store.inner, wasm_byte_slice));

Some(Box::new(wasm_module_t {
inner: Arc::new(module),
Expand All @@ -32,6 +31,23 @@ pub unsafe extern "C" fn wasm_module_new(
#[no_mangle]
pub unsafe extern "C" fn wasm_module_delete(_module: Option<Box<wasm_module_t>>) {}

#[no_mangle]
pub unsafe extern "C" fn wasm_module_validate(
store: &wasm_store_t,
bytes: &wasm_byte_vec_t,
) -> bool {
// TODO: review lifetime of byte slice.
let wasm_byte_slice: &[u8] = slice::from_raw_parts(bytes.data, bytes.size);

if let Err(error) = Module::validate(&store.inner, wasm_byte_slice) {
update_last_error(error);

false
} else {
true
}
}

#[no_mangle]
pub unsafe extern "C" fn wasm_module_exports(
module: &wasm_module_t,
Expand Down Expand Up @@ -64,7 +80,7 @@ pub unsafe extern "C" fn wasm_module_imports(

#[no_mangle]
pub unsafe extern "C" fn wasm_module_deserialize(
store_ptr: Option<NonNull<wasm_store_t>>,
store: &wasm_store_t,
bytes: *const wasm_byte_vec_t,
) -> Option<NonNull<wasm_module_t>> {
// TODO: read config from store and use that to decide which compiler to use
Expand All @@ -76,9 +92,7 @@ pub unsafe extern "C" fn wasm_module_deserialize(
(&*bytes).into_slice().unwrap()
};

let store_ptr: NonNull<Store> = store_ptr?.cast::<Store>();
let store = store_ptr.as_ref();
let module = c_try!(Module::deserialize(store, byte_slice));
let module = c_try!(Module::deserialize(&store.inner, byte_slice));

Some(NonNull::new_unchecked(Box::into_raw(Box::new(
wasm_module_t {
Expand All @@ -92,7 +106,7 @@ pub unsafe extern "C" fn wasm_module_serialize(
module: &wasm_module_t,
out_ptr: &mut wasm_byte_vec_t,
) {
let mut byte_vec = match module.inner.serialize() {
let byte_vec = match module.inner.serialize() {
Ok(byte_vec) => byte_vec,
Err(_) => return,
};
Expand Down
19 changes: 7 additions & 12 deletions lib/c-api/src/wasm_c_api/store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,20 @@ use wasmer::Store;

/// Opaque wrapper around `Store`
#[allow(non_camel_case_types)]
pub struct wasm_store_t {}
pub struct wasm_store_t {
pub(crate) inner: Store,
}

#[no_mangle]
pub unsafe extern "C" fn wasm_store_new(
wasm_engine_ptr: Option<NonNull<wasm_engine_t>>,
) -> Option<NonNull<wasm_store_t>> {
) -> Option<Box<wasm_store_t>> {
let wasm_engine_ptr = wasm_engine_ptr?;
let wasm_engine = wasm_engine_ptr.as_ref();
let store = Store::new(&*wasm_engine.inner);
Some(NonNull::new_unchecked(
Box::into_raw(Box::new(store)) as *mut wasm_store_t
))

Some(Box::new(wasm_store_t { inner: store }))
}

#[no_mangle]
pub unsafe extern "C" fn wasm_store_delete(wasm_store: Option<NonNull<wasm_store_t>>) {
if let Some(s_inner) = wasm_store {
// this should not leak memory:
// we should double check it to make sure though
let _: Box<Store> = Box::from_raw(s_inner.cast::<Store>().as_ptr());
}
}
pub unsafe extern "C" fn wasm_store_delete(_store: Option<Box<wasm_store_t>>) {}
10 changes: 4 additions & 6 deletions lib/c-api/src/wasm_c_api/wasi/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,8 @@ use crate::error::{update_last_error, CApiError};
use std::convert::TryFrom;
use std::ffi::CStr;
use std::os::raw::c_char;
use std::ptr::NonNull;
use std::slice;
use wasmer::{Extern, NamedResolver, Store};
use wasmer::{Extern, NamedResolver};
use wasmer_wasi::{
generate_import_object_from_env, get_wasi_version, WasiEnv, WasiFile, WasiState,
WasiStateBuilder, WasiVersion,
Expand Down Expand Up @@ -241,7 +240,7 @@ pub unsafe extern "C" fn wasi_get_wasi_version(module: &wasm_module_t) -> wasi_v
/// Takes ownership of `wasi_env_t`.
#[no_mangle]
pub unsafe extern "C" fn wasi_get_imports(
store: Option<NonNull<wasm_store_t>>,
store: &wasm_store_t,
module: &wasm_module_t,
wasi_env: &wasi_env_t,
imports: *mut *mut wasm_extern_t,
Expand All @@ -251,13 +250,12 @@ pub unsafe extern "C" fn wasi_get_imports(

/// Takes ownership of `wasi_env_t`.
unsafe fn wasi_get_imports_inner(
store: Option<NonNull<wasm_store_t>>,
store: &wasm_store_t,
module: &wasm_module_t,
wasi_env: &wasi_env_t,
imports: *mut *mut wasm_extern_t,
) -> Option<()> {
let store_ptr = store?.cast::<Store>();
let store = store_ptr.as_ref();
let store = &store.inner;

let version = c_try!(
get_wasi_version(&module.inner, false).ok_or_else(|| CApiError {
Expand Down

0 comments on commit 205318d

Please sign in to comment.