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