mirror of
https://github.com/mii443/wasmer.git
synced 2025-12-08 05:38:19 +00:00
Improved Module api along with Exports
This commit is contained in:
@@ -7,7 +7,7 @@ use std::sync::Arc;
|
|||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
use wasmer_compiler::{CompileError, WasmError};
|
use wasmer_compiler::{CompileError, WasmError};
|
||||||
use wasmer_jit::{CompiledModule, DeserializeError, Resolver, SerializeError};
|
use wasmer_jit::{CompiledModule, DeserializeError, Resolver, SerializeError};
|
||||||
use wasmer_runtime::InstanceHandle;
|
use wasmer_runtime::{ExportsIterator, InstanceHandle, Module as ModuleInfo};
|
||||||
|
|
||||||
#[derive(Error, Debug)]
|
#[derive(Error, Debug)]
|
||||||
pub enum IoCompileError {
|
pub enum IoCompileError {
|
||||||
@@ -274,11 +274,21 @@ impl Module {
|
|||||||
/// export.ty();
|
/// export.ty();
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
pub fn exports<'a>(&'a self) -> impl Iterator<Item = ExportType> + 'a {
|
pub fn exports<'a>(&'a self) -> ExportsIterator<impl Iterator<Item = ExportType> + 'a> {
|
||||||
self.compiled.module().exports()
|
self.compiled.module().exports()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn store(&self) -> &Store {
|
pub fn store(&self) -> &Store {
|
||||||
&self.store
|
&self.store
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The ABI of the ModuleInfo is very unstable, we refactor it very often.
|
||||||
|
// This funciton is public because in some cases it can be useful to get some
|
||||||
|
// extra information from the module.
|
||||||
|
//
|
||||||
|
// However, the usage is highly discouraged.
|
||||||
|
#[doc(hidden)]
|
||||||
|
pub fn info(&self) -> &ModuleInfo {
|
||||||
|
&self.compiled.module()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -339,7 +339,7 @@ impl Instance {
|
|||||||
|
|
||||||
/// Return an iterator over the exports of this instance.
|
/// Return an iterator over the exports of this instance.
|
||||||
///
|
///
|
||||||
/// Specifically, it provides access to the key-value pairs, where they keys
|
/// Specifically, it provides access to the key-value pairs, where the keys
|
||||||
/// are export names, and the values are export declarations which can be
|
/// are export names, and the values are export declarations which can be
|
||||||
/// resolved `lookup_by_declaration`.
|
/// resolved `lookup_by_declaration`.
|
||||||
pub fn exports(&self) -> indexmap::map::Iter<String, ExportIndex> {
|
pub fn exports(&self) -> indexmap::map::Iter<String, ExportIndex> {
|
||||||
|
|||||||
@@ -41,7 +41,9 @@ pub use crate::imports::Imports;
|
|||||||
pub use crate::instance::InstanceHandle;
|
pub use crate::instance::InstanceHandle;
|
||||||
pub use crate::memory::LinearMemory;
|
pub use crate::memory::LinearMemory;
|
||||||
pub use crate::mmap::Mmap;
|
pub use crate::mmap::Mmap;
|
||||||
pub use crate::module::{MemoryPlan, MemoryStyle, Module, TableElements, TablePlan, TableStyle};
|
pub use crate::module::{
|
||||||
|
ExportsIterator, MemoryPlan, MemoryStyle, Module, TableElements, TablePlan, TableStyle,
|
||||||
|
};
|
||||||
pub use crate::probestack::PROBESTACK;
|
pub use crate::probestack::PROBESTACK;
|
||||||
pub use crate::sig_registry::SignatureRegistry;
|
pub use crate::sig_registry::SignatureRegistry;
|
||||||
pub use crate::table::Table;
|
pub use crate::table::Table;
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ use indexmap::IndexMap;
|
|||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
use std::iter::ExactSizeIterator;
|
||||||
use std::sync::atomic::{AtomicUsize, Ordering::SeqCst};
|
use std::sync::atomic::{AtomicUsize, Ordering::SeqCst};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use wasm_common::entity::{EntityRef, PrimaryMap};
|
use wasm_common::entity::{EntityRef, PrimaryMap};
|
||||||
@@ -134,7 +135,7 @@ pub struct Module {
|
|||||||
/// WebAssembly function signatures.
|
/// WebAssembly function signatures.
|
||||||
pub signatures: PrimaryMap<SignatureIndex, FunctionType>,
|
pub signatures: PrimaryMap<SignatureIndex, FunctionType>,
|
||||||
|
|
||||||
/// Types of functions (imported and local).
|
/// WebAssembly functions (imported and local).
|
||||||
pub functions: PrimaryMap<FunctionIndex, SignatureIndex>,
|
pub functions: PrimaryMap<FunctionIndex, SignatureIndex>,
|
||||||
|
|
||||||
/// WebAssembly tables (imported and local).
|
/// WebAssembly tables (imported and local).
|
||||||
@@ -206,8 +207,8 @@ impl Module {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Get the export types of the module
|
/// Get the export types of the module
|
||||||
pub fn exports<'a>(&'a self) -> impl Iterator<Item = ExportType> + 'a {
|
pub fn exports<'a>(&'a self) -> ExportsIterator<impl Iterator<Item = ExportType> + 'a> {
|
||||||
self.exports.iter().map(move |(name, export_index)| {
|
let iter = self.exports.iter().map(move |(name, export_index)| {
|
||||||
let extern_type = match export_index {
|
let extern_type = match export_index {
|
||||||
ExportIndex::Function(i) => {
|
ExportIndex::Function(i) => {
|
||||||
let signature = self.functions.get(i.clone()).unwrap();
|
let signature = self.functions.get(i.clone()).unwrap();
|
||||||
@@ -228,7 +229,11 @@ impl Module {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
ExportType::new(name, extern_type)
|
ExportType::new(name, extern_type)
|
||||||
})
|
});
|
||||||
|
ExportsIterator {
|
||||||
|
iter,
|
||||||
|
size: self.exports.len(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the export types of the module
|
/// Get the export types of the module
|
||||||
@@ -348,3 +353,56 @@ impl fmt::Display for Module {
|
|||||||
write!(f, "{}", self.name())
|
write!(f, "{}", self.name())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Code inspired from
|
||||||
|
// https://www.reddit.com/r/rust/comments/9vspv4/extending_iterators_ergonomically/
|
||||||
|
/// This iterator allows us to iterate
|
||||||
|
pub struct ExportsIterator<I: Iterator<Item = ExportType> + Sized> {
|
||||||
|
iter: I,
|
||||||
|
size: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<I: Iterator<Item = ExportType> + Sized> ExactSizeIterator for ExportsIterator<I> {
|
||||||
|
// We can easily calculate the remaining number of iterations.
|
||||||
|
fn len(&self) -> usize {
|
||||||
|
self.size
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<I: Iterator<Item = ExportType> + Sized> ExportsIterator<I> {
|
||||||
|
/// Get only the functions
|
||||||
|
pub fn functions(self) -> impl Iterator<Item = ExportType<FunctionType>> + Sized {
|
||||||
|
self.iter.filter_map(|extern_| match extern_.ty() {
|
||||||
|
ExternType::Function(ty) => Some(ExportType::new(extern_.name(), ty.clone())),
|
||||||
|
_ => None,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
/// Get only the memories
|
||||||
|
pub fn memories(self) -> impl Iterator<Item = ExportType<MemoryType>> + Sized {
|
||||||
|
self.iter.filter_map(|extern_| match extern_.ty() {
|
||||||
|
ExternType::Memory(ty) => Some(ExportType::new(extern_.name(), ty.clone())),
|
||||||
|
_ => None,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
/// Get only the tables
|
||||||
|
pub fn tables(self) -> impl Iterator<Item = ExportType<TableType>> + Sized {
|
||||||
|
self.iter.filter_map(|extern_| match extern_.ty() {
|
||||||
|
ExternType::Table(ty) => Some(ExportType::new(extern_.name(), ty.clone())),
|
||||||
|
_ => None,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
/// Get only the globals
|
||||||
|
pub fn globals(self) -> impl Iterator<Item = ExportType<GlobalType>> + Sized {
|
||||||
|
self.iter.filter_map(|extern_| match extern_.ty() {
|
||||||
|
ExternType::Global(ty) => Some(ExportType::new(extern_.name(), ty.clone())),
|
||||||
|
_ => None,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<I: Iterator<Item = ExportType> + Sized> Iterator for ExportsIterator<I> {
|
||||||
|
type Item = ExportType;
|
||||||
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
self.iter.next()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -502,17 +502,21 @@ impl ImportType {
|
|||||||
/// [`Module::exports`](crate::Module::exports) accessor and describes what
|
/// [`Module::exports`](crate::Module::exports) accessor and describes what
|
||||||
/// names are exported from a wasm module and the type of the item that is
|
/// names are exported from a wasm module and the type of the item that is
|
||||||
/// exported.
|
/// exported.
|
||||||
|
///
|
||||||
|
/// The `<T>` refefers to `ExternType`, however it can also refer to use
|
||||||
|
/// `MemoryType`, `TableType`, `FunctionType` and `GlobalType` for ease of
|
||||||
|
/// use.
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
|
||||||
pub struct ExportType {
|
pub struct ExportType<T = ExternType> {
|
||||||
name: String,
|
name: String,
|
||||||
ty: ExternType,
|
ty: T,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ExportType {
|
impl<T> ExportType<T> {
|
||||||
/// Creates a new export which is exported with the given `name` and has the
|
/// Creates a new export which is exported with the given `name` and has the
|
||||||
/// given `ty`.
|
/// given `ty`.
|
||||||
pub fn new(name: &str, ty: ExternType) -> ExportType {
|
pub fn new(name: &str, ty: T) -> Self {
|
||||||
ExportType {
|
ExportType {
|
||||||
name: name.to_string(),
|
name: name.to_string(),
|
||||||
ty,
|
ty,
|
||||||
@@ -525,7 +529,7 @@ impl ExportType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the type of this export.
|
/// Returns the type of this export.
|
||||||
pub fn ty(&self) -> &ExternType {
|
pub fn ty(&self) -> &T {
|
||||||
&self.ty
|
&self.ty
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user