Coverage Report

Created: 2021-03-22 08:29

/src/wasm-tools/crates/wasm-encoder/src/imports.rs
Line
Count
Source (jump to first uncovered line)
1
use super::*;
2
use std::convert::TryFrom;
3
4
/// An encoder for the import section.
5
///
6
/// # Example
7
///
8
/// ```
9
/// use wasm_encoder::{Module, ImportSection, MemoryType, Limits};
10
///
11
/// let mut imports = ImportSection::new();
12
/// imports.import(
13
///     "env",
14
///     Some("memory"),
15
///     MemoryType {
16
///         limits: Limits {
17
///             min: 1,
18
///             max: None,
19
///         }
20
///     }
21
/// );
22
///
23
/// let mut module = Module::new();
24
/// module.section(&imports);
25
///
26
/// let wasm_bytes = module.finish();
27
/// ```
28
0
#[derive(Clone, Debug)]
29
pub struct ImportSection {
30
    bytes: Vec<u8>,
31
    num_added: u32,
32
}
33
34
impl ImportSection {
35
    /// Construct a new import section encoder.
36
316k
    pub fn new() -> ImportSection {
37
316k
        ImportSection {
38
316k
            bytes: vec![],
39
316k
            num_added: 0,
40
316k
        }
41
316k
    }
42
43
    /// Define an import.
44
1.30M
    pub fn import(
45
1.30M
        &mut self,
46
1.30M
        module: &str,
47
1.30M
        name: Option<&str>,
48
1.30M
        ty: impl Into<EntityType>,
49
1.30M
    ) -> &mut Self {
50
1.30M
        self.bytes.extend(encoders::str(module));
51
1.30M
        match name {
52
745k
            Some(name) => self.bytes.extend(encoders::str(name)),
53
559k
            None => {
54
559k
                self.bytes.push(0x00);
55
559k
                self.bytes.push(0xff);
56
559k
            }
57
        }
58
1.30M
        ty.into().encode(&mut self.bytes);
59
1.30M
        self.num_added += 1;
60
1.30M
        self
61
1.30M
    }
62
}
63
64
impl Section for ImportSection {
65
316k
    fn id(&self) -> u8 {
66
316k
        SectionId::Import.into()
67
316k
    }
68
69
316k
    fn encode<S>(&self, sink: &mut S)
70
316k
    where
71
316k
        S: Extend<u8>,
72
316k
    {
73
316k
        let num_added = encoders::u32(self.num_added);
74
316k
        let n = num_added.len();
75
316k
        sink.extend(
76
316k
            encoders::u32(u32::try_from(n + self.bytes.len()).unwrap())
77
316k
                .chain(num_added)
78
316k
                .chain(self.bytes.iter().copied()),
79
316k
        );
80
316k
    }
81
}
82
83
/// The type of an entity.
84
0
#[derive(Clone, Copy, Debug)]
85
pub enum EntityType {
86
    /// The `n`th type, which is a function.
87
    Function(u32),
88
    /// A table type.
89
    Table(TableType),
90
    /// A memory type.
91
    Memory(MemoryType),
92
    /// A global type.
93
    Global(GlobalType),
94
    /// The `n`th type, which is an instance.
95
    Instance(u32),
96
    /// The `n`th type, which is a module.
97
    Module(u32),
98
}
99
100
// NB: no `impl From<u32> for ImportType` because instances and modules also use
101
// `u32` indices in module linking, so we would have to remove that impl when
102
// adding support for module linking anyways.
103
104
impl From<TableType> for EntityType {
105
807k
    fn from(t: TableType) -> Self {
106
807k
        EntityType::Table(t)
107
807k
    }
108
}
109
110
impl From<MemoryType> for EntityType {
111
541k
    fn from(m: MemoryType) -> Self {
112
541k
        EntityType::Memory(m)
113
541k
    }
114
}
115
116
impl From<GlobalType> for EntityType {
117
968k
    fn from(g: GlobalType) -> Self {
118
968k
        EntityType::Global(g)
119
968k
    }
120
}
121
122
impl EntityType {
123
3.38M
    pub(crate) fn encode(&self, dst: &mut Vec<u8>) {
124
3.38M
        match self {
125
473k
            EntityType::Function(x) => {
126
473k
                dst.push(0x00);
127
473k
                dst.extend(encoders::u32(*x));
128
473k
            }
129
807k
            EntityType::Table(ty) => {
130
807k
                dst.push(0x01);
131
807k
                ty.encode(dst);
132
807k
            }
133
541k
            EntityType::Memory(ty) => {
134
541k
                dst.push(0x02);
135
541k
                ty.encode(dst);
136
541k
            }
137
968k
            EntityType::Global(ty) => {
138
968k
                dst.push(0x03);
139
968k
                ty.encode(dst);
140
968k
            }
141
519k
            EntityType::Module(ty) => {
142
519k
                dst.push(0x05);
143
519k
                dst.extend(encoders::u32(*ty));
144
519k
            }
145
73.4k
            EntityType::Instance(ty) => {
146
73.4k
                dst.push(0x06);
147
73.4k
                dst.extend(encoders::u32(*ty));
148
73.4k
            }
149
        }
150
3.38M
    }
151
}