Improved imports iterator

This commit is contained in:
Syrus
2020-05-04 18:24:24 -07:00
parent 6e56597f86
commit 5f68aff8bd
4 changed files with 89 additions and 13 deletions

View File

@@ -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::{ExportsIterator, InstanceHandle, Module as ModuleInfo}; use wasmer_runtime::{ExportsIterator, ImportsIterator, InstanceHandle, Module as ModuleInfo};
#[derive(Error, Debug)] #[derive(Error, Debug)]
pub enum IoCompileError { pub enum IoCompileError {
@@ -263,7 +263,7 @@ impl Module {
/// import.ty(); /// import.ty();
/// } /// }
/// ``` /// ```
pub fn imports<'a>(&'a self) -> impl Iterator<Item = ImportType> + 'a { pub fn imports<'a>(&'a self) -> ImportsIterator<impl Iterator<Item = ImportType> + 'a> {
self.compiled.module().imports() self.compiled.module().imports()
} }

View File

@@ -42,7 +42,8 @@ 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::{ pub use crate::module::{
ExportsIterator, MemoryPlan, MemoryStyle, Module, TableElements, TablePlan, TableStyle, ExportsIterator, ImportsIterator, 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;

View File

@@ -237,8 +237,9 @@ impl Module {
} }
/// Get the export types of the module /// Get the export types of the module
pub fn imports<'a>(&'a self) -> impl Iterator<Item = ImportType> + 'a { pub fn imports<'a>(&'a self) -> ImportsIterator<impl Iterator<Item = ImportType> + 'a> {
self.imports let iter = self
.imports
.iter() .iter()
.map(move |((module, field, _), import_index)| { .map(move |((module, field, _), import_index)| {
let extern_type = match import_index { let extern_type = match import_index {
@@ -261,7 +262,11 @@ impl Module {
} }
}; };
ImportType::new(module, field, extern_type) ImportType::new(module, field, extern_type)
}) });
ImportsIterator {
iter,
size: self.imports.len(),
}
} }
/// Convert a `LocalFunctionIndex` into a `FunctionIndex`. /// Convert a `LocalFunctionIndex` into a `FunctionIndex`.
@@ -356,7 +361,9 @@ impl fmt::Display for Module {
// Code inspired from // Code inspired from
// https://www.reddit.com/r/rust/comments/9vspv4/extending_iterators_ergonomically/ // https://www.reddit.com/r/rust/comments/9vspv4/extending_iterators_ergonomically/
/// This iterator allows us to iterate
/// This iterator allows us to iterate over the exports
/// and offer nice API ergonomics over it.
pub struct ExportsIterator<I: Iterator<Item = ExportType> + Sized> { pub struct ExportsIterator<I: Iterator<Item = ExportType> + Sized> {
iter: I, iter: I,
size: usize, size: usize,
@@ -406,3 +413,71 @@ impl<I: Iterator<Item = ExportType> + Sized> Iterator for ExportsIterator<I> {
self.iter.next() self.iter.next()
} }
} }
/// This iterator allows us to iterate over the imports
/// and offer nice API ergonomics over it.
pub struct ImportsIterator<I: Iterator<Item = ImportType> + Sized> {
iter: I,
size: usize,
}
impl<I: Iterator<Item = ImportType> + Sized> ExactSizeIterator for ImportsIterator<I> {
// We can easily calculate the remaining number of iterations.
fn len(&self) -> usize {
self.size
}
}
impl<I: Iterator<Item = ImportType> + Sized> ImportsIterator<I> {
/// Get only the functions
pub fn functions(self) -> impl Iterator<Item = ImportType<FunctionType>> + Sized {
self.iter.filter_map(|extern_| match extern_.ty() {
ExternType::Function(ty) => Some(ImportType::new(
extern_.module(),
extern_.name(),
ty.clone(),
)),
_ => None,
})
}
/// Get only the memories
pub fn memories(self) -> impl Iterator<Item = ImportType<MemoryType>> + Sized {
self.iter.filter_map(|extern_| match extern_.ty() {
ExternType::Memory(ty) => Some(ImportType::new(
extern_.module(),
extern_.name(),
ty.clone(),
)),
_ => None,
})
}
/// Get only the tables
pub fn tables(self) -> impl Iterator<Item = ImportType<TableType>> + Sized {
self.iter.filter_map(|extern_| match extern_.ty() {
ExternType::Table(ty) => Some(ImportType::new(
extern_.module(),
extern_.name(),
ty.clone(),
)),
_ => None,
})
}
/// Get only the globals
pub fn globals(self) -> impl Iterator<Item = ImportType<GlobalType>> + Sized {
self.iter.filter_map(|extern_| match extern_.ty() {
ExternType::Global(ty) => Some(ImportType::new(
extern_.module(),
extern_.name(),
ty.clone(),
)),
_ => None,
})
}
}
impl<I: Iterator<Item = ImportType> + Sized> Iterator for ImportsIterator<I> {
type Item = ImportType;
fn next(&mut self) -> Option<Self::Item> {
self.iter.next()
}
}

View File

@@ -491,17 +491,17 @@ impl std::fmt::Display for MemoryType {
/// imported from as well as the type of item that's being imported. /// imported from as well as the type of item that's being imported.
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
pub struct ImportType { pub struct ImportType<T = ExternType> {
module: String, module: String,
name: String, name: String,
ty: ExternType, ty: T,
} }
impl ImportType { impl<T> ImportType<T> {
/// Creates a new import descriptor which comes from `module` and `name` and /// Creates a new import descriptor which comes from `module` and `name` and
/// is of type `ty`. /// is of type `ty`.
pub fn new(module: &str, name: &str, ty: ExternType) -> ImportType { pub fn new(module: &str, name: &str, ty: T) -> Self {
ImportType { Self {
module: module.to_owned(), module: module.to_owned(),
name: name.to_owned(), name: name.to_owned(),
ty, ty,
@@ -520,7 +520,7 @@ impl ImportType {
} }
/// Returns the expected type of this import. /// Returns the expected type of this import.
pub fn ty(&self) -> &ExternType { pub fn ty(&self) -> &T {
&self.ty &self.ty
} }
} }