diff --git a/lib/api/src/module.rs b/lib/api/src/module.rs index 739f853a2..4d5e9d390 100644 --- a/lib/api/src/module.rs +++ b/lib/api/src/module.rs @@ -7,7 +7,7 @@ use std::sync::Arc; use thiserror::Error; use wasmer_compiler::{CompileError, WasmError}; 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)] pub enum IoCompileError { @@ -263,7 +263,7 @@ impl Module { /// import.ty(); /// } /// ``` - pub fn imports<'a>(&'a self) -> impl Iterator + 'a { + pub fn imports<'a>(&'a self) -> ImportsIterator + 'a> { self.compiled.module().imports() } diff --git a/lib/runtime/src/lib.rs b/lib/runtime/src/lib.rs index e9e649721..bad8455d5 100644 --- a/lib/runtime/src/lib.rs +++ b/lib/runtime/src/lib.rs @@ -42,7 +42,8 @@ pub use crate::instance::InstanceHandle; pub use crate::memory::LinearMemory; pub use crate::mmap::Mmap; 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::sig_registry::SignatureRegistry; diff --git a/lib/runtime/src/module.rs b/lib/runtime/src/module.rs index fff482bd3..c5311835c 100644 --- a/lib/runtime/src/module.rs +++ b/lib/runtime/src/module.rs @@ -237,8 +237,9 @@ impl Module { } /// Get the export types of the module - pub fn imports<'a>(&'a self) -> impl Iterator + 'a { - self.imports + pub fn imports<'a>(&'a self) -> ImportsIterator + 'a> { + let iter = self + .imports .iter() .map(move |((module, field, _), import_index)| { let extern_type = match import_index { @@ -261,7 +262,11 @@ impl Module { } }; ImportType::new(module, field, extern_type) - }) + }); + ImportsIterator { + iter, + size: self.imports.len(), + } } /// Convert a `LocalFunctionIndex` into a `FunctionIndex`. @@ -356,7 +361,9 @@ impl fmt::Display for Module { // Code inspired from // 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 + Sized> { iter: I, size: usize, @@ -406,3 +413,71 @@ impl + Sized> Iterator for ExportsIterator { self.iter.next() } } + +/// This iterator allows us to iterate over the imports +/// and offer nice API ergonomics over it. +pub struct ImportsIterator + Sized> { + iter: I, + size: usize, +} + +impl + Sized> ExactSizeIterator for ImportsIterator { + // We can easily calculate the remaining number of iterations. + fn len(&self) -> usize { + self.size + } +} + +impl + Sized> ImportsIterator { + /// Get only the functions + pub fn functions(self) -> impl Iterator> + 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> + 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> + 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> + Sized { + self.iter.filter_map(|extern_| match extern_.ty() { + ExternType::Global(ty) => Some(ImportType::new( + extern_.module(), + extern_.name(), + ty.clone(), + )), + _ => None, + }) + } +} + +impl + Sized> Iterator for ImportsIterator { + type Item = ImportType; + fn next(&mut self) -> Option { + self.iter.next() + } +} diff --git a/lib/wasm-common/src/types.rs b/lib/wasm-common/src/types.rs index eabb49402..4c3529b54 100644 --- a/lib/wasm-common/src/types.rs +++ b/lib/wasm-common/src/types.rs @@ -491,17 +491,17 @@ impl std::fmt::Display for MemoryType { /// imported from as well as the type of item that's being imported. #[derive(Debug, Clone)] #[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] -pub struct ImportType { +pub struct ImportType { module: String, name: String, - ty: ExternType, + ty: T, } -impl ImportType { +impl ImportType { /// Creates a new import descriptor which comes from `module` and `name` and /// is of type `ty`. - pub fn new(module: &str, name: &str, ty: ExternType) -> ImportType { - ImportType { + pub fn new(module: &str, name: &str, ty: T) -> Self { + Self { module: module.to_owned(), name: name.to_owned(), ty, @@ -520,7 +520,7 @@ impl ImportType { } /// Returns the expected type of this import. - pub fn ty(&self) -> &ExternType { + pub fn ty(&self) -> &T { &self.ty } }