1 | use alloc::borrow::Cow; |
2 | use alloc::vec::Vec; |
3 | |
4 | use super::*; |
5 | use crate::{encoding_size, ExportKind, NameMap, SectionId}; |
6 | |
7 | /// Encoding for the `component-name` custom section which assigns |
8 | /// human-readable names to items within a component. |
9 | #[derive (Clone, Debug, Default)] |
10 | pub struct ComponentNameSection { |
11 | bytes: Vec<u8>, |
12 | } |
13 | |
14 | enum Subsection { |
15 | Component, |
16 | Decls, |
17 | } |
18 | |
19 | impl ComponentNameSection { |
20 | /// Creates a new blank `name` custom section. |
21 | pub fn new() -> Self { |
22 | Self::default() |
23 | } |
24 | |
25 | /// Appends a component name subsection to this section. |
26 | /// |
27 | /// This will indicate that the name of the entire component should be the |
28 | /// `name` specified. Note that this should be encoded first before other |
29 | /// subsections. |
30 | pub fn component(&mut self, name: &str) { |
31 | let len = encoding_size(u32::try_from(name.len()).unwrap()); |
32 | self.subsection_header(Subsection::Component, len + name.len()); |
33 | name.encode(&mut self.bytes); |
34 | } |
35 | |
36 | /// Appends a decls name subsection to name core functions within the |
37 | /// component. |
38 | pub fn core_funcs(&mut self, names: &NameMap) { |
39 | self.core_decls(ExportKind::Func as u8, names) |
40 | } |
41 | |
42 | /// Appends a decls name subsection to name core tables within the |
43 | /// component. |
44 | pub fn core_tables(&mut self, names: &NameMap) { |
45 | self.core_decls(ExportKind::Table as u8, names) |
46 | } |
47 | |
48 | /// Appends a decls name subsection to name core memories within the |
49 | /// component. |
50 | pub fn core_memories(&mut self, names: &NameMap) { |
51 | self.core_decls(ExportKind::Memory as u8, names) |
52 | } |
53 | |
54 | /// Appends a decls name subsection to name core globals within the |
55 | /// component. |
56 | pub fn core_globals(&mut self, names: &NameMap) { |
57 | self.core_decls(ExportKind::Global as u8, names) |
58 | } |
59 | |
60 | /// Appends a decls name subsection to name core types within the |
61 | /// component. |
62 | pub fn core_types(&mut self, names: &NameMap) { |
63 | self.core_decls(CORE_TYPE_SORT, names) |
64 | } |
65 | |
66 | /// Appends a decls name subsection to name core modules within the |
67 | /// component. |
68 | pub fn core_modules(&mut self, names: &NameMap) { |
69 | self.core_decls(CORE_MODULE_SORT, names) |
70 | } |
71 | |
72 | /// Appends a decls name subsection to name core instances within the |
73 | /// component. |
74 | pub fn core_instances(&mut self, names: &NameMap) { |
75 | self.core_decls(CORE_INSTANCE_SORT, names) |
76 | } |
77 | |
78 | /// Appends a decls name subsection to name component functions within the |
79 | /// component. |
80 | pub fn funcs(&mut self, names: &NameMap) { |
81 | self.component_decls(FUNCTION_SORT, names) |
82 | } |
83 | |
84 | /// Appends a decls name subsection to name component values within the |
85 | /// component. |
86 | pub fn values(&mut self, names: &NameMap) { |
87 | self.component_decls(VALUE_SORT, names) |
88 | } |
89 | |
90 | /// Appends a decls name subsection to name component type within the |
91 | /// component. |
92 | pub fn types(&mut self, names: &NameMap) { |
93 | self.component_decls(TYPE_SORT, names) |
94 | } |
95 | |
96 | /// Appends a decls name subsection to name components within the |
97 | /// component. |
98 | pub fn components(&mut self, names: &NameMap) { |
99 | self.component_decls(COMPONENT_SORT, names) |
100 | } |
101 | |
102 | /// Appends a decls name subsection to name component instances within the |
103 | /// component. |
104 | pub fn instances(&mut self, names: &NameMap) { |
105 | self.component_decls(INSTANCE_SORT, names) |
106 | } |
107 | |
108 | /// Appends a raw subsection with the given id and data. |
109 | pub fn raw(&mut self, id: u8, data: &[u8]) { |
110 | self.bytes.push(id); |
111 | data.encode(&mut self.bytes); |
112 | } |
113 | |
114 | fn component_decls(&mut self, kind: u8, names: &NameMap) { |
115 | self.subsection_header(Subsection::Decls, 1 + names.size()); |
116 | self.bytes.push(kind); |
117 | names.encode(&mut self.bytes); |
118 | } |
119 | |
120 | fn core_decls(&mut self, kind: u8, names: &NameMap) { |
121 | self.subsection_header(Subsection::Decls, 2 + names.size()); |
122 | self.bytes.push(CORE_SORT); |
123 | self.bytes.push(kind); |
124 | names.encode(&mut self.bytes); |
125 | } |
126 | |
127 | fn subsection_header(&mut self, id: Subsection, len: usize) { |
128 | self.bytes.push(id as u8); |
129 | len.encode(&mut self.bytes); |
130 | } |
131 | |
132 | /// Returns whether this section is empty, or nothing has been encoded. |
133 | pub fn is_empty(&self) -> bool { |
134 | self.bytes.is_empty() |
135 | } |
136 | |
137 | /// View the encoded section as a CustomSection. |
138 | pub fn as_custom<'a>(&'a self) -> CustomSection<'a> { |
139 | CustomSection { |
140 | name: "component-name" .into(), |
141 | data: Cow::Borrowed(&self.bytes), |
142 | } |
143 | } |
144 | } |
145 | |
146 | impl Encode for ComponentNameSection { |
147 | fn encode(&self, sink: &mut Vec<u8>) { |
148 | self.as_custom().encode(sink); |
149 | } |
150 | } |
151 | |
152 | impl ComponentSection for ComponentNameSection { |
153 | fn id(&self) -> u8 { |
154 | SectionId::Custom.into() |
155 | } |
156 | } |
157 | |