wasmi/module/import.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
use crate::{GlobalType, MemoryType, TableType};
use core::fmt::{self, Display};
use std::boxed::Box;
use wasmparser::TypeRef;
/// A [`Module`] import item.
///
/// [`Module`]: [`super::Module`]
#[derive(Debug)]
pub struct Import {
/// The name of the imported item.
name: ImportName,
/// The type of the imported item.
kind: ExternTypeIdx,
}
/// The name or namespace of an imported item.
#[derive(Debug, Clone)]
pub struct ImportName {
/// The name of the [`Module`] that defines the imported item.
///
/// [`Module`]: [`super::Module`]
module: Box<str>,
/// The name of the imported item within the [`Module`] namespace.
///
/// [`Module`]: [`super::Module`]
field: Box<str>,
}
impl Display for ImportName {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let module_name = &*self.module;
let field_name = &*self.field;
write!(f, "{module_name}::{field_name}")
}
}
impl ImportName {
/// Creates a new [`Import`] item.
pub fn new(module: &str, field: &str) -> Self {
Self {
module: module.into(),
field: field.into(),
}
}
/// Returns the name of the [`Module`] that defines the imported item.
///
/// [`Module`]: [`super::Module`]
pub fn module(&self) -> &str {
&self.module
}
/// Returns the name of the imported item within the [`Module`] namespace.
///
/// [`Module`]: [`super::Module`]
pub fn name(&self) -> &str {
&self.field
}
}
impl From<wasmparser::Import<'_>> for Import {
fn from(import: wasmparser::Import) -> Self {
let kind = match import.ty {
TypeRef::Func(ty) => ExternTypeIdx::Func(ty.into()),
TypeRef::Table(ty) => ExternTypeIdx::Table(TableType::from_wasmparser(ty)),
TypeRef::Memory(ty) => ExternTypeIdx::Memory(MemoryType::from_wasmparser(ty)),
TypeRef::Global(ty) => ExternTypeIdx::Global(GlobalType::from_wasmparser(ty)),
TypeRef::Tag(tag) => panic!(
"wasmi does not support the `exception-handling` Wasm proposal but found: {tag:?}"
),
};
Self::new(import.module, import.name, kind)
}
}
impl Import {
/// Creates a new [`Import`] item.
pub fn new(module: &str, field: &str, kind: ExternTypeIdx) -> Self {
Self {
name: ImportName::new(module, field),
kind,
}
}
/// Splits the [`Import`] into its raw parts.
///
/// # Note
///
/// This allows to reuse some allocations in certain cases.
pub fn into_name_and_type(self) -> (ImportName, ExternTypeIdx) {
(self.name, self.kind)
}
}
/// The kind of a [`Module`] import.
///
/// [`Module`]: [`super::Module`]
#[derive(Debug)]
pub enum ExternTypeIdx {
/// An imported function.
Func(FuncTypeIdx),
/// An imported table.
Table(TableType),
/// An imported linear memory.
Memory(MemoryType),
/// An imported global variable.
Global(GlobalType),
}
/// A [`FuncType`] index.
///
/// # Note
///
/// This generally refers to a [`FuncType`] within the same [`Module`]
/// and is used by both function declarations and function imports.
///
/// [`Module`]: [`super::Module`]
/// [`FuncType`]: [`crate::FuncType`]
#[derive(Debug, Copy, Clone)]
pub struct FuncTypeIdx(u32);
impl From<u32> for FuncTypeIdx {
fn from(index: u32) -> Self {
Self(index)
}
}
impl FuncTypeIdx {
/// Returns the inner `u32` index of the [`FuncTypeIdx`].
pub fn into_u32(self) -> u32 {
self.0
}
}