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