Skip to content

Commit

Permalink
Merge pull request #3141 from wasmerio/feat_api_change_from_wasix
Browse files Browse the repository at this point in the history
The API breaking changes from future WASIX/Network/Threading addition
  • Loading branch information
syrusakbary authored Sep 2, 2022
2 parents dafdd94 + 2752f7d commit e259738
Show file tree
Hide file tree
Showing 13 changed files with 146 additions and 31 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 2 additions & 3 deletions docs/migration_to_3.0.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -195,14 +195,13 @@ import_object.define("env", "host_function", host_function);
let instance = Instance::new(&mut store, &module, &import_object).expect("Could not instantiate module.");
```

For WASI, don't forget to import memory to `WasiEnv`
For WASI, don't forget to initialize the `WasiEnv` (it will import the memory)

```rust
let mut wasi_env = WasiState::new("hello").finalize()?;
let import_object = wasi_env.import_object(&mut store, &module)?;
let instance = Instance::new(&mut store, &module, &import_object).expect("Could not instantiate module.");
let memory = instance.exports.get_memory("memory")?;
wasi_env.data_mut(&mut store).set_memory(memory.clone());
wasi_env.initialize(&mut store, &instance).unwrap();
```

#### `ChainableNamedResolver` is removed
Expand Down
1 change: 1 addition & 0 deletions lib/api/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ indexmap = { version = "1.6" }
cfg-if = "1.0"
thiserror = "1.0"
more-asserts = "0.2"
bytes = "1"
# - Optional shared dependencies.
wat = { version = "1.0", optional = true }
tracing = { version = "0.1", optional = true }
Expand Down
51 changes: 47 additions & 4 deletions lib/api/src/js/module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ use crate::js::store::AsStoreMut;
use crate::js::types::{AsJs, ExportType, ImportType};
use crate::js::RuntimeError;
use crate::AsStoreRef;
use bytes::Bytes;
use js_sys::{Reflect, Uint8Array, WebAssembly};
use std::borrow::Cow;
use std::fmt;
use std::io;
use std::path::Path;
Expand Down Expand Up @@ -48,6 +50,46 @@ pub struct ModuleTypeHints {
pub exports: Vec<ExternType>,
}

pub trait IntoBytes {
fn into_bytes(self) -> Bytes;
}

impl IntoBytes for Bytes {
fn into_bytes(self) -> Bytes {
self
}
}

impl IntoBytes for Vec<u8> {
fn into_bytes(self) -> Bytes {
Bytes::from(self)
}
}

impl IntoBytes for &[u8] {
fn into_bytes(self) -> Bytes {
Bytes::from(self.to_vec())
}
}

impl<const N: usize> IntoBytes for &[u8; N] {
fn into_bytes(self) -> Bytes {
Bytes::from(self.to_vec())
}
}

impl IntoBytes for &str {
fn into_bytes(self) -> Bytes {
Bytes::from(self.as_bytes().to_vec())
}
}

impl IntoBytes for Cow<'_, [u8]> {
fn into_bytes(self) -> Bytes {
Bytes::from(self.to_vec())
}
}

/// A WebAssembly Module contains stateless WebAssembly
/// code that has already been compiled and can be instantiated
/// multiple times.
Expand All @@ -63,7 +105,7 @@ pub struct Module {
// WebAssembly type hints
type_hints: Option<ModuleTypeHints>,
#[cfg(feature = "js-serializable-module")]
raw_bytes: Option<Vec<u8>>,
raw_bytes: Option<Bytes>,
}

impl Module {
Expand Down Expand Up @@ -199,7 +241,7 @@ impl Module {
type_hints,
name,
#[cfg(feature = "js-serializable-module")]
raw_bytes: Some(binary.to_vec()),
raw_bytes: Some(binary.into_bytes()),
})
}

Expand Down Expand Up @@ -263,7 +305,7 @@ impl Module {
/// can later process via [`Module::deserialize`].
///
#[cfg(feature = "js-serializable-module")]
pub fn serialize(&self) -> Result<Vec<u8>, SerializeError> {
pub fn serialize(&self) -> Result<Bytes, SerializeError> {
self.raw_bytes.clone().ok_or(SerializeError::Generic(
"Not able to serialize module".to_string(),
))
Expand All @@ -276,8 +318,9 @@ impl Module {
#[cfg(feature = "js-serializable-module")]
pub unsafe fn deserialize(
_store: &impl AsStoreRef,
bytes: &[u8],
bytes: impl IntoBytes,
) -> Result<Self, DeserializeError> {
let bytes = bytes.into_bytes();
Self::new(_store, bytes).map_err(|e| DeserializeError::Compiler(e))
}

Expand Down
2 changes: 1 addition & 1 deletion lib/api/src/js/ptr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ impl<T, M: MemorySize> WasmPtr<T, M> {

/// Get the offset into Wasm linear memory for this `WasmPtr`.
#[inline]
pub fn offset(self) -> M::Offset {
pub fn offset(&self) -> M::Offset {
self.offset
}

Expand Down
7 changes: 6 additions & 1 deletion lib/api/src/sys/function_env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ impl<T> FunctionEnv<T> {
}

/// Get the data as reference
pub fn as_ref<'a>(&self, store: &'a impl AsStoreMut) -> &'a T
pub fn as_ref<'a>(&self, store: &'a impl AsStoreRef) -> &'a T
where
T: Any + Send + 'static + Sized,
{
Expand Down Expand Up @@ -105,6 +105,11 @@ impl<T: Send + 'static> FunctionEnvMut<'_, T> {
self.func_env.as_mut(&mut self.store_mut)
}

/// Borrows a new immmutable reference
pub fn as_ref(&self) -> FunctionEnv<T> {
self.func_env.clone()
}

/// Borrows a new mutable reference
pub fn as_mut(&mut self) -> FunctionEnvMut<'_, T> {
FunctionEnvMut {
Expand Down
52 changes: 47 additions & 5 deletions lib/api/src/sys/module.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
use crate::sys::InstantiationError;
use crate::AsStoreMut;
use crate::AsStoreRef;
use bytes::Bytes;
use std::borrow::Cow;
use std::fmt;
use std::io;
use std::path::Path;
Expand Down Expand Up @@ -54,6 +56,46 @@ pub struct Module {
module_info: Arc<ModuleInfo>,
}

pub trait IntoBytes {
fn into_bytes(self) -> Bytes;
}

impl IntoBytes for Bytes {
fn into_bytes(self) -> Bytes {
self
}
}

impl IntoBytes for Vec<u8> {
fn into_bytes(self) -> Bytes {
Bytes::from(self)
}
}

impl IntoBytes for &[u8] {
fn into_bytes(self) -> Bytes {
Bytes::from(self.to_vec())
}
}

impl<const N: usize> IntoBytes for &[u8; N] {
fn into_bytes(self) -> Bytes {
Bytes::from(self.to_vec())
}
}

impl IntoBytes for &str {
fn into_bytes(self) -> Bytes {
Bytes::from(self.as_bytes().to_vec())
}
}

impl IntoBytes for Cow<'_, [u8]> {
fn into_bytes(self) -> Bytes {
Bytes::from(self.to_vec())
}
}

impl Module {
#[cfg(feature = "compiler")]
/// Creates a new WebAssembly Module given the configuration
Expand Down Expand Up @@ -124,7 +166,6 @@ impl Module {
e
)))
})?;

Self::from_binary(store, bytes.as_ref())
}

Expand Down Expand Up @@ -206,8 +247,8 @@ impl Module {
/// # Ok(())
/// # }
/// ```
pub fn serialize(&self) -> Result<Vec<u8>, SerializeError> {
self.artifact.serialize()
pub fn serialize(&self) -> Result<Bytes, SerializeError> {
self.artifact.serialize().map(|bytes| bytes.into())
}

/// Serializes a module into a file that the `Engine`
Expand Down Expand Up @@ -254,9 +295,10 @@ impl Module {
/// ```
pub unsafe fn deserialize(
store: &impl AsStoreRef,
bytes: &[u8],
bytes: impl IntoBytes,
) -> Result<Self, DeserializeError> {
let artifact = store.as_store_ref().engine().deserialize(bytes)?;
let bytes = bytes.into_bytes();
let artifact = store.as_store_ref().engine().deserialize(&bytes)?;
Ok(Self::from_artifact(artifact))
}

Expand Down
2 changes: 1 addition & 1 deletion lib/api/src/sys/ptr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ impl<T, M: MemorySize> WasmPtr<T, M> {

/// Get the offset into Wasm linear memory for this `WasmPtr`.
#[inline]
pub fn offset(self) -> M::Offset {
pub fn offset(&self) -> M::Offset {
self.offset
}

Expand Down
2 changes: 1 addition & 1 deletion lib/c-api/src/wasm_c_api/module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -475,7 +475,7 @@ pub unsafe extern "C" fn wasm_module_deserialize(
#[no_mangle]
pub unsafe extern "C" fn wasm_module_serialize(module: &wasm_module_t, out: &mut wasm_byte_vec_t) {
let byte_vec = c_try!(module.inner.serialize(); otherwise ());
out.set_buffer(byte_vec);
out.set_buffer(byte_vec.to_vec());
}

#[cfg(test)]
Expand Down
15 changes: 5 additions & 10 deletions lib/cli/src/commands/inspect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,11 @@ impl Inspect {
fn inner_execute(&self) -> Result<()> {
let (store, _compiler_type) = self.store.get_store()?;
let module_contents = std::fs::read(&self.path)?;
let module = Module::new(&store, &module_contents)?;
println!(
"Type: {}",
if !is_wasm(&module_contents) {
"wat"
} else {
"wasm"
}
);
println!("Size: {}", ByteSize(module_contents.len() as _));
let iswasm = is_wasm(&module_contents);
let module_len = module_contents.len();
let module = Module::new(&store, module_contents)?;
println!("Type: {}", if !iswasm { "wat" } else { "wasm" });
println!("Size: {}", ByteSize(module_len as _));
println!("Imports:");
println!(" Functions:");
for f in module.imports().functions() {
Expand Down
4 changes: 2 additions & 2 deletions lib/cli/src/commands/run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@ impl Run {
let module_result: Result<Module> = if !self.disable_cache && contents.len() > 0x1000 {
self.get_module_from_cache(&store, &contents, &compiler_type)
} else {
Module::new(&store, &contents).map_err(|e| e.into())
Module::new(&store, contents).map_err(|e| e.into())
};
#[cfg(not(feature = "cache"))]
let module_result = Module::new(&store, &contents);
Expand Down Expand Up @@ -319,7 +319,7 @@ impl Run {
warning!("cached module is corrupted: {}", err);
}
}
let module = Module::new(store, &contents)?;
let module = Module::new(store, contents)?;
// Store the compiled Module in cache
cache.store(hash, &module)?;
Ok(module)
Expand Down
33 changes: 31 additions & 2 deletions lib/wasi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,11 @@ use wasmer_wasi_types::__WASI_CLOCK_MONOTONIC;
use derivative::*;
use std::ops::Deref;
use thiserror::Error;
use tracing::trace;
use wasmer::{
imports, namespace, AsStoreMut, AsStoreRef, Exports, Function, FunctionEnv, Imports, Memory,
Memory32, MemoryAccessError, MemorySize, MemoryView, Module, TypedFunction,
imports, namespace, AsStoreMut, AsStoreRef, ExportError, Exports, Function, FunctionEnv,
Imports, Instance, Memory, Memory32, MemoryAccessError, MemorySize, MemoryView, Module,
TypedFunction,
};

pub use runtime::{
Expand Down Expand Up @@ -166,6 +168,33 @@ impl WasiFunctionEnv {
self.env.as_mut(store)
}

/// Initializes the WasiEnv using the instance exports
/// (this must be executed before attempting to use it)
/// (as the stores can not by themselves be passed between threads we can store the module
/// in a thread-local variables and use it later - for multithreading)
pub fn initialize(
&mut self,
store: &mut impl AsStoreMut,
instance: &Instance,
) -> Result<(), ExportError> {
// List all the exports and imports
for ns in instance.module().exports() {
//trace!("module::export - {} ({:?})", ns.name(), ns.ty());
trace!("module::export - {}", ns.name());
}
for ns in instance.module().imports() {
trace!("module::import - {}::{}", ns.module(), ns.name());
}

// First we get the malloc function which if it exists will be used to
// create the pthread_self structure
let memory = instance.exports.get_memory("memory")?.clone();
let env = self.data_mut(store);
env.set_memory(memory);

Ok(())
}

/// Like `import_object` but containing all the WASI versions detected in
/// the module.
pub fn import_object_for_all_wasi_versions(
Expand Down
2 changes: 1 addition & 1 deletion tests/compilers/serialize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ fn test_deserialize(config: crate::Config) -> Result<()> {
let serialized_bytes = module.serialize()?;

let headless_store = config.headless_store();
let deserialized_module = unsafe { Module::deserialize(&headless_store, &serialized_bytes)? };
let deserialized_module = unsafe { Module::deserialize(&headless_store, serialized_bytes)? };
assert_eq!(deserialized_module.name(), Some("name"));
assert_eq!(
deserialized_module.exports().collect::<Vec<_>>(),
Expand Down

0 comments on commit e259738

Please sign in to comment.