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
    }
}