Improve consistency and add misc clean ups

This commit is contained in:
Mark McCaskey
2020-03-31 12:37:50 -07:00
parent 403d4b4c8b
commit 50fcd57e45
4 changed files with 102 additions and 75 deletions

View File

@ -80,27 +80,27 @@ fn module_exports_are_ordered() {
vec![ vec![
export::ExportDescriptor { export::ExportDescriptor {
name: "test-table", name: "test-table",
kind: export::ExportKind::Table, ty: export::ExportType::Table,
}, },
export::ExportDescriptor { export::ExportDescriptor {
name: "test-global", name: "test-global",
kind: export::ExportKind::Global, ty: export::ExportType::Global,
}, },
export::ExportDescriptor { export::ExportDescriptor {
name: "ret_2", name: "ret_2",
kind: export::ExportKind::Function, ty: export::ExportType::Function,
}, },
export::ExportDescriptor { export::ExportDescriptor {
name: "ret_4", name: "ret_4",
kind: export::ExportKind::Function, ty: export::ExportType::Function,
}, },
export::ExportDescriptor { export::ExportDescriptor {
name: "set_test_global", name: "set_test_global",
kind: export::ExportKind::Function, ty: export::ExportType::Function,
}, },
export::ExportDescriptor { export::ExportDescriptor {
name: "update_outside_global", name: "update_outside_global",
kind: export::ExportKind::Function, ty: export::ExportType::Function,
}, },
] ]
); );

View File

@ -22,15 +22,12 @@
//! //!
//! more info, what to do if you run into problems //! more info, what to do if you run into problems
/// Commonly used types and functions. pub use crate::module::*;
pub mod prelude { pub use wasmer_runtime_core::instance::{DynFunc, Instance};
pub use crate::module::*; pub use wasmer_runtime_core::memory::Memory;
pub use wasmer_runtime_core::instance::{DynFunc, Instance}; pub use wasmer_runtime_core::table::Table;
pub use wasmer_runtime_core::memory::Memory; pub use wasmer_runtime_core::Func;
pub use wasmer_runtime_core::table::Table; pub use wasmer_runtime_core::{func, imports};
pub use wasmer_runtime_core::Func;
pub use wasmer_runtime_core::{func, imports};
}
pub mod module { pub mod module {
//! Types and functions for WebAssembly modules. //! Types and functions for WebAssembly modules.
@ -51,7 +48,7 @@ pub mod module {
// TODO: verify that this is the type we want to export, with extra methods on it // TODO: verify that this is the type we want to export, with extra methods on it
pub use wasmer_runtime_core::module::Module; pub use wasmer_runtime_core::module::Module;
// should this be in here? // should this be in here?
pub use wasmer_runtime_core::module::{ExportDescriptor, ExportKind, Import, ImportType}; pub use wasmer_runtime_core::module::{ExportDescriptor, ExportType, Import, ImportDescriptor};
// TODO: implement abstract module API // TODO: implement abstract module API
} }
@ -69,7 +66,7 @@ pub mod wasm {
//! //!
//! # Tables //! # Tables
pub use wasmer_runtime_core::global::Global; pub use wasmer_runtime_core::global::Global;
pub use wasmer_runtime_core::module::{ExportDescriptor, ExportKind, Import, ImportType}; pub use wasmer_runtime_core::module::{ExportDescriptor, ExportType, Import, ImportDescriptor};
pub use wasmer_runtime_core::table::Table; pub use wasmer_runtime_core::table::Table;
pub use wasmer_runtime_core::types::{ pub use wasmer_runtime_core::types::{
FuncSig, GlobalDescriptor, MemoryDescriptor, TableDescriptor, Type, Value, FuncSig, GlobalDescriptor, MemoryDescriptor, TableDescriptor, Type, Value,
@ -78,13 +75,13 @@ pub mod wasm {
pub mod import { pub mod import {
//! Types and functions for Wasm imports. //! Types and functions for Wasm imports.
pub use wasmer_runtime_core::module::{Import, ImportType}; pub use wasmer_runtime_core::module::{Import, ImportDescriptor};
pub use wasmer_runtime_core::{func, imports}; pub use wasmer_runtime_core::{func, imports};
} }
pub mod export { pub mod export {
//! Types and functions for Wasm exports. //! Types and functions for Wasm exports.
pub use wasmer_runtime_core::module::{ExportDescriptor, ExportKind}; pub use wasmer_runtime_core::module::{ExportDescriptor, ExportType};
} }
pub mod units { pub mod units {
@ -100,16 +97,49 @@ pub mod types {
pub mod error { pub mod error {
//! Various error types returned by Wasmer APIs. //! Various error types returned by Wasmer APIs.
pub use wasmer_runtime_core::error::{CompileError, CompileResult}; pub use wasmer_runtime_core::error::{CompileError, CompileResult};
}
pub use prelude::*; #[derive(Debug)]
pub enum CompileFromFileError {
CompileError(CompileError),
IoError(std::io::Error),
}
impl std::fmt::Display for CompileFromFileError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
CompileFromFileError::CompileError(ce) => write!(f, "{}", ce),
CompileFromFileError::IoError(ie) => write!(f, "{}", ie),
}
}
}
impl std::error::Error for CompileFromFileError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {
CompileFromFileError::CompileError(ce) => Some(ce),
CompileFromFileError::IoError(ie) => Some(ie),
}
}
}
impl From<CompileError> for CompileFromFileError {
fn from(other: CompileError) -> Self {
CompileFromFileError::CompileError(other)
}
}
impl From<std::io::Error> for CompileFromFileError {
fn from(other: std::io::Error) -> Self {
CompileFromFileError::IoError(other)
}
}
}
/// Idea for generic trait; consider rename; it will need to be moved somewhere else /// Idea for generic trait; consider rename; it will need to be moved somewhere else
pub trait CompiledModule { pub trait CompiledModule {
fn new(bytes: impl AsRef<[u8]>) -> error::CompileResult<Module>; fn new(bytes: impl AsRef<[u8]>) -> error::CompileResult<Module>;
fn from_binary(bytes: impl AsRef<[u8]>) -> error::CompileResult<Module>; fn from_binary(bytes: impl AsRef<[u8]>) -> error::CompileResult<Module>;
fn from_binary_unchecked(bytes: impl AsRef<[u8]>) -> error::CompileResult<Module>; fn from_binary_unchecked(bytes: impl AsRef<[u8]>) -> error::CompileResult<Module>;
fn from_file(file: impl AsRef<std::path::Path>) -> error::CompileResult<Module>; fn from_file(file: impl AsRef<std::path::Path>) -> Result<Module, error::CompileFromFileError>;
fn validate(bytes: impl AsRef<[u8]>) -> error::CompileResult<()>; fn validate(bytes: impl AsRef<[u8]>) -> error::CompileResult<()>;
} }
@ -156,30 +186,31 @@ impl CompiledModule for Module {
wasmer_runtime_core::compile_with(bytes, &default_compiler()) wasmer_runtime_core::compile_with(bytes, &default_compiler())
} }
fn from_binary(_bytes: impl AsRef<[u8]>) -> error::CompileResult<Module> { fn from_binary(bytes: impl AsRef<[u8]>) -> error::CompileResult<Module> {
todo!("from_binary: how is this different from `new`?") let bytes = bytes.as_ref();
wasmer_runtime_core::compile_with(bytes, &default_compiler())
} }
fn from_binary_unchecked(_bytes: impl AsRef<[u8]>) -> error::CompileResult<Module> {
todo!("from_binary_unchecked") fn from_binary_unchecked(bytes: impl AsRef<[u8]>) -> error::CompileResult<Module> {
// TODO: optimize this
Self::from_binary(bytes)
} }
fn from_file(_file: impl AsRef<std::path::Path>) -> error::CompileResult<Module> {
todo!("from_file"); fn from_file(file: impl AsRef<std::path::Path>) -> Result<Module, error::CompileFromFileError> {
/*
use std::fs; use std::fs;
use std::io::Read; use std::io::Read;
let path = file.as_ref(); let path = file.as_ref();
let mut f = let mut f = fs::File::open(path)?;
fs::File::open(path).map_err(|_| todo!("Current error enum can't handle this case"))?;
// TODO: ideally we can support a streaming compilation API and not have to read in the entire file // TODO: ideally we can support a streaming compilation API and not have to read in the entire file
let mut bytes = vec![]; let mut bytes = vec![];
f.read_to_end(&mut bytes) f.read_to_end(&mut bytes)?;
.map_err(|_| todo!("Current error enum can't handle this case"))?;
Module::from_binary(bytes.as_slice()) Ok(Module::from_binary(bytes.as_slice())?)
*/
} }
fn validate(_bytes: impl AsRef<[u8]>) -> error::CompileResult<()> { fn validate(bytes: impl AsRef<[u8]>) -> error::CompileResult<()> {
todo!("validate") // TODO: optimize this
let _ = Self::from_binary(bytes)?;
Ok(())
} }
} }

View File

@ -56,7 +56,7 @@ pub struct Instance {
/// Reference to the module used to instantiate this instance. /// Reference to the module used to instantiate this instance.
pub module: Arc<ModuleInner>, pub module: Arc<ModuleInner>,
inner: Pin<Box<InstanceInner>>, inner: Pin<Box<InstanceInner>>,
/// The exports of this instance. TODO: document this /// The exports of this instance.
pub exports: Exports, pub exports: Exports,
#[allow(dead_code)] #[allow(dead_code)]
import_object: ImportObject, import_object: ImportObject,
@ -894,7 +894,8 @@ impl<'a, Args: WasmTypeList, Rets: WasmTypeList> Exportable<'a> for Func<'a, Arg
pub struct Exports { pub struct Exports {
// We want to avoid the borrow checker here. // We want to avoid the borrow checker here.
// This is safe because // This is safe because
// 1. `Exports` can't be constructed or copied (so can't safely outlive `Instance`) // 1. `Exports` can't be constructed, its fields inspected (directly or via methods),
// or copied outside of this module/in Instance, so it can't safely outlive `Instance`.
// 2. `InstanceInner` is `Pin<Box<>>`, thus we know that it will not move. // 2. `InstanceInner` is `Pin<Box<>>`, thus we know that it will not move.
instance_inner: *const InstanceInner, instance_inner: *const InstanceInner,
module: Arc<ModuleInner>, module: Arc<ModuleInner>,
@ -931,7 +932,7 @@ impl Exports {
T::get_self(self, name) T::get_self(self, name)
} }
/// This method must remain private. /// This method must remain private for `Exports` to be sound.
fn get_inner(&self) -> (&InstanceInner, &ModuleInner) { fn get_inner(&self) -> (&InstanceInner, &ModuleInner) {
let inst_inner = unsafe { &*self.instance_inner }; let inst_inner = unsafe { &*self.instance_inner };
let module = self.module.borrow(); let module = self.module.borrow();

View File

@ -176,18 +176,18 @@ impl Module {
/// ``` /// ```
/// # use wasmer_runtime_core::module::*; /// # use wasmer_runtime_core::module::*;
/// # fn example(module: &Module) { /// # fn example(module: &Module) {
/// // We can filter by `ExportKind` to get only certain types of exports. /// // We can filter by `ExportType` to get only certain types of exports.
/// // For example, here we get all the names of the functions exported by this module. /// // For example, here we get all the names of the functions exported by this module.
/// let function_names = /// let function_names =
/// module.exports() /// module.exports()
/// .filter(|ed| ed.kind == ExportKind::Function) /// .filter(|ed| ed.kind == ExportType::Function)
/// .map(|ed| ed.name.to_string()) /// .map(|ed| ed.name.to_string())
/// .collect::<Vec<String>>(); /// .collect::<Vec<String>>();
/// ///
/// // And here we count the number of global variables exported by this module. /// // And here we count the number of global variables exported by this module.
/// let num_globals = /// let num_globals =
/// module.exports() /// module.exports()
/// .filter(|ed| ed.kind == ExportKind::Global) /// .filter(|ed| ed.kind == ExportType::Global)
/// .count(); /// .count();
/// # } /// # }
/// ``` /// ```
@ -198,7 +198,7 @@ impl Module {
.iter() .iter()
.map(|(name, &ei)| ExportDescriptor { .map(|(name, &ei)| ExportDescriptor {
name, name,
kind: ei.into(), ty: ei.into(),
}) })
} }
@ -236,7 +236,7 @@ impl Module {
Import { Import {
namespace, namespace,
name, name,
ty: sig.into(), descriptor: sig.into(),
} }
}); });
let imported_memories = let imported_memories =
@ -247,7 +247,7 @@ impl Module {
Import { Import {
namespace, namespace,
name, name,
ty: memory_descriptor.into(), descriptor: memory_descriptor.into(),
} }
}); });
let imported_tables = let imported_tables =
@ -258,7 +258,7 @@ impl Module {
Import { Import {
namespace, namespace,
name, name,
ty: table_descriptor.into(), descriptor: table_descriptor.into(),
} }
}); });
let imported_globals = let imported_globals =
@ -269,7 +269,7 @@ impl Module {
Import { Import {
namespace, namespace,
name, name,
ty: global_descriptor.into(), descriptor: global_descriptor.into(),
} }
}); });
@ -287,20 +287,18 @@ impl Module {
} }
} }
// TODO: review this vs `ExportIndex`
/// Type describing an export that the [`Module`] provides. /// Type describing an export that the [`Module`] provides.
#[derive(Debug, Clone, PartialEq, Eq, Hash)] #[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct ExportDescriptor<'a> { pub struct ExportDescriptor<'a> {
/// The name identifying the export. /// The name identifying the export.
pub name: &'a str, pub name: &'a str,
/// The type of the export. /// The type of the export.
pub kind: ExportKind, pub ty: ExportType,
} }
// TODO: kind vs type
/// Tag indicating the type of the export. /// Tag indicating the type of the export.
#[derive(Debug, Clone, PartialEq, Eq, Hash)] #[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum ExportKind { pub enum ExportType {
/// The export is a function. /// The export is a function.
Function, Function,
/// The export is a global variable. /// The export is a global variable.
@ -311,7 +309,7 @@ pub enum ExportKind {
Table, Table,
} }
impl From<ExportIndex> for ExportKind { impl From<ExportIndex> for ExportType {
fn from(other: ExportIndex) -> Self { fn from(other: ExportIndex) -> Self {
match other { match other {
ExportIndex::Func(_) => Self::Function, ExportIndex::Func(_) => Self::Function,
@ -330,12 +328,9 @@ impl Clone for Module {
} }
} }
/// The type of import. This indicates whether the import is a function, global, memory, or table. /// Information about an import such as its type and metadata about the import.
// TODO: discuss and research Kind vs Type;
// `Kind` has meaning to me from Haskell as an incomplete type like
// `List` which is of kind `* -> *`.
#[derive(Debug, Clone, PartialEq, Eq)] #[derive(Debug, Clone, PartialEq, Eq)]
pub enum ImportType { pub enum ImportDescriptor {
/// The import is a function. /// The import is a function.
Function(FuncDescriptor), Function(FuncDescriptor),
/// The import is a global variable. /// The import is a global variable.
@ -346,45 +341,45 @@ pub enum ImportType {
Table(TableDescriptor), Table(TableDescriptor),
} }
impl From<FuncDescriptor> for ImportType { impl From<FuncDescriptor> for ImportDescriptor {
fn from(other: FuncDescriptor) -> Self { fn from(other: FuncDescriptor) -> Self {
ImportType::Function(other) ImportDescriptor::Function(other)
} }
} }
impl From<&FuncDescriptor> for ImportType { impl From<&FuncDescriptor> for ImportDescriptor {
fn from(other: &FuncDescriptor) -> Self { fn from(other: &FuncDescriptor) -> Self {
ImportType::Function(other.clone()) ImportDescriptor::Function(other.clone())
} }
} }
impl From<MemoryDescriptor> for ImportType { impl From<MemoryDescriptor> for ImportDescriptor {
fn from(other: MemoryDescriptor) -> Self { fn from(other: MemoryDescriptor) -> Self {
ImportType::Memory(other) ImportDescriptor::Memory(other)
} }
} }
impl From<&MemoryDescriptor> for ImportType { impl From<&MemoryDescriptor> for ImportDescriptor {
fn from(other: &MemoryDescriptor) -> Self { fn from(other: &MemoryDescriptor) -> Self {
ImportType::Memory(*other) ImportDescriptor::Memory(*other)
} }
} }
impl From<TableDescriptor> for ImportType { impl From<TableDescriptor> for ImportDescriptor {
fn from(other: TableDescriptor) -> Self { fn from(other: TableDescriptor) -> Self {
ImportType::Table(other) ImportDescriptor::Table(other)
} }
} }
impl From<&TableDescriptor> for ImportType { impl From<&TableDescriptor> for ImportDescriptor {
fn from(other: &TableDescriptor) -> Self { fn from(other: &TableDescriptor) -> Self {
ImportType::Table(*other) ImportDescriptor::Table(*other)
} }
} }
impl From<GlobalDescriptor> for ImportType { impl From<GlobalDescriptor> for ImportDescriptor {
fn from(other: GlobalDescriptor) -> Self { fn from(other: GlobalDescriptor) -> Self {
ImportType::Global(other) ImportDescriptor::Global(other)
} }
} }
impl From<&GlobalDescriptor> for ImportType { impl From<&GlobalDescriptor> for ImportDescriptor {
fn from(other: &GlobalDescriptor) -> Self { fn from(other: &GlobalDescriptor) -> Self {
ImportType::Global(*other) ImportDescriptor::Global(*other)
} }
} }
@ -396,7 +391,7 @@ pub struct Import {
/// The name of the import. /// The name of the import.
pub name: String, pub name: String,
/// The type of the import. /// The type of the import.
pub ty: ImportType, pub descriptor: ImportDescriptor,
} }
impl ModuleInner {} impl ModuleInner {}