/rust/registry/src/index.crates.io-6f17d22bba15001f/wast-64.0.0/src/component/instance.rs
Line | Count | Source (jump to first uncovered line) |
1 | | use crate::component::*; |
2 | | use crate::core; |
3 | | use crate::kw; |
4 | | use crate::parser::{Parse, Parser, Result}; |
5 | | use crate::token::{Id, LParen, NameAnnotation, Span}; |
6 | | |
7 | | /// A core instance defined by instantiation or exporting core items. |
8 | | #[derive(Debug)] |
9 | | pub struct CoreInstance<'a> { |
10 | | /// Where this `core instance` was defined. |
11 | | pub span: Span, |
12 | | /// An identifier that this instance is resolved with (optionally) for name |
13 | | /// resolution. |
14 | | pub id: Option<Id<'a>>, |
15 | | /// An optional name for this instance stored in the custom `name` section. |
16 | | pub name: Option<NameAnnotation<'a>>, |
17 | | /// What kind of instance this is. |
18 | | pub kind: CoreInstanceKind<'a>, |
19 | | } |
20 | | |
21 | | impl<'a> Parse<'a> for CoreInstance<'a> { |
22 | 0 | fn parse(parser: Parser<'a>) -> Result<Self> { |
23 | 0 | let span = parser.parse::<kw::core>()?.0; |
24 | 0 | parser.parse::<kw::instance>()?; |
25 | 0 | let id = parser.parse()?; |
26 | 0 | let name = parser.parse()?; |
27 | 0 | let kind = parser.parse()?; |
28 | | |
29 | 0 | Ok(Self { |
30 | 0 | span, |
31 | 0 | id, |
32 | 0 | name, |
33 | 0 | kind, |
34 | 0 | }) |
35 | 0 | } |
36 | | } |
37 | | |
38 | | /// The kinds of core instances in the text format. |
39 | | #[derive(Debug)] |
40 | | pub enum CoreInstanceKind<'a> { |
41 | | /// Instantiate a core module. |
42 | | Instantiate { |
43 | | /// The module being instantiated. |
44 | | module: ItemRef<'a, kw::module>, |
45 | | /// Arguments used to instantiate the instance. |
46 | | args: Vec<CoreInstantiationArg<'a>>, |
47 | | }, |
48 | | /// The instance is defined by exporting local items as an instance. |
49 | | BundleOfExports(Vec<CoreInstanceExport<'a>>), |
50 | | } |
51 | | |
52 | | impl<'a> Parse<'a> for CoreInstanceKind<'a> { |
53 | 0 | fn parse(parser: Parser<'a>) -> Result<Self> { |
54 | 0 | if parser.peek::<LParen>()? && parser.peek2::<kw::instantiate>()? { |
55 | 0 | parser.parens(|parser| { |
56 | 0 | parser.parse::<kw::instantiate>()?; |
57 | | Ok(Self::Instantiate { |
58 | 0 | module: parser.parse::<IndexOrRef<'_, _>>()?.0, |
59 | 0 | args: parser.parse()?, |
60 | | }) |
61 | 0 | }) |
62 | | } else { |
63 | 0 | Ok(Self::BundleOfExports(parser.parse()?)) |
64 | | } |
65 | 0 | } |
66 | | } |
67 | | |
68 | | impl Default for kw::module { |
69 | 0 | fn default() -> kw::module { |
70 | 0 | kw::module(Span::from_offset(0)) |
71 | 0 | } |
72 | | } |
73 | | |
74 | | /// An argument to instantiate a core module. |
75 | | #[derive(Debug)] |
76 | | pub struct CoreInstantiationArg<'a> { |
77 | | /// The name of the instantiation argument. |
78 | | pub name: &'a str, |
79 | | /// The kind of core instantiation argument. |
80 | | pub kind: CoreInstantiationArgKind<'a>, |
81 | | } |
82 | | |
83 | | impl<'a> Parse<'a> for CoreInstantiationArg<'a> { |
84 | 0 | fn parse(parser: Parser<'a>) -> Result<Self> { |
85 | 0 | parser.parse::<kw::with>()?; |
86 | | Ok(Self { |
87 | 0 | name: parser.parse()?, |
88 | 0 | kind: parser.parse()?, |
89 | | }) |
90 | 0 | } |
91 | | } |
92 | | |
93 | | impl<'a> Parse<'a> for Vec<CoreInstantiationArg<'a>> { |
94 | 0 | fn parse(parser: Parser<'a>) -> Result<Self> { |
95 | 0 | let mut args = Vec::new(); |
96 | 0 | while !parser.is_empty() { |
97 | 0 | args.push(parser.parens(|parser| parser.parse())?); |
98 | | } |
99 | 0 | Ok(args) |
100 | 0 | } |
101 | | } |
102 | | |
103 | | /// The kind of core instantiation argument. |
104 | | #[derive(Debug)] |
105 | | pub enum CoreInstantiationArgKind<'a> { |
106 | | /// The argument is a reference to an instance. |
107 | | Instance(CoreItemRef<'a, kw::instance>), |
108 | | /// The argument is an instance created from local exported core items. |
109 | | /// |
110 | | /// This is syntactic sugar for defining a core instance and also using it |
111 | | /// as an instantiation argument. |
112 | | BundleOfExports(Span, Vec<CoreInstanceExport<'a>>), |
113 | | } |
114 | | |
115 | | impl<'a> Parse<'a> for CoreInstantiationArgKind<'a> { |
116 | 0 | fn parse(parser: Parser<'a>) -> Result<Self> { |
117 | 0 | parser.parens(|parser| { |
118 | 0 | if let Some(r) = parser.parse()? { |
119 | 0 | Ok(Self::Instance(r)) |
120 | | } else { |
121 | 0 | let span = parser.parse::<kw::instance>()?.0; |
122 | 0 | Ok(Self::BundleOfExports(span, parser.parse()?)) |
123 | | } |
124 | 0 | }) |
125 | 0 | } |
126 | | } |
127 | | |
128 | | /// An exported item as part of a core instance. |
129 | | #[derive(Debug)] |
130 | | pub struct CoreInstanceExport<'a> { |
131 | | /// Where this export was defined. |
132 | | pub span: Span, |
133 | | /// The name of this export from the instance. |
134 | | pub name: &'a str, |
135 | | /// What's being exported from the instance. |
136 | | pub item: CoreItemRef<'a, core::ExportKind>, |
137 | | } |
138 | | |
139 | | impl<'a> Parse<'a> for CoreInstanceExport<'a> { |
140 | 0 | fn parse(parser: Parser<'a>) -> Result<Self> { |
141 | 0 | Ok(Self { |
142 | 0 | span: parser.parse::<kw::export>()?.0, |
143 | 0 | name: parser.parse()?, |
144 | 0 | item: parser.parens(|parser| parser.parse())?, |
145 | | }) |
146 | 0 | } |
147 | | } |
148 | | |
149 | | impl<'a> Parse<'a> for Vec<CoreInstanceExport<'a>> { |
150 | 0 | fn parse(parser: Parser<'a>) -> Result<Self> { |
151 | 0 | let mut exports = Vec::new(); |
152 | 0 | while !parser.is_empty() { |
153 | 0 | exports.push(parser.parens(|parser| parser.parse())?); |
154 | | } |
155 | 0 | Ok(exports) |
156 | 0 | } |
157 | | } |
158 | | |
159 | | /// A component instance defined by instantiation or exporting items. |
160 | | #[derive(Debug)] |
161 | | pub struct Instance<'a> { |
162 | | /// Where this `instance` was defined. |
163 | | pub span: Span, |
164 | | /// An identifier that this instance is resolved with (optionally) for name |
165 | | /// resolution. |
166 | | pub id: Option<Id<'a>>, |
167 | | /// An optional name for this instance stored in the custom `name` section. |
168 | | pub name: Option<NameAnnotation<'a>>, |
169 | | /// If present, inline export annotations which indicate names this |
170 | | /// definition should be exported under. |
171 | | pub exports: InlineExport<'a>, |
172 | | /// What kind of instance this is. |
173 | | pub kind: InstanceKind<'a>, |
174 | | } |
175 | | |
176 | | impl<'a> Parse<'a> for Instance<'a> { |
177 | 0 | fn parse(parser: Parser<'a>) -> Result<Self> { |
178 | 0 | let span = parser.parse::<kw::instance>()?.0; |
179 | 0 | let id = parser.parse()?; |
180 | 0 | let name = parser.parse()?; |
181 | 0 | let exports = parser.parse()?; |
182 | 0 | let kind = parser.parse()?; |
183 | | |
184 | 0 | Ok(Self { |
185 | 0 | span, |
186 | 0 | id, |
187 | 0 | name, |
188 | 0 | exports, |
189 | 0 | kind, |
190 | 0 | }) |
191 | 0 | } |
192 | | } |
193 | | |
194 | | /// The kinds of instances in the text format. |
195 | | #[derive(Debug)] |
196 | | pub enum InstanceKind<'a> { |
197 | | /// The `(instance (import "x"))` sugar syntax |
198 | | Import { |
199 | | /// The name of the import |
200 | | import: InlineImport<'a>, |
201 | | /// The type of the instance being imported |
202 | | ty: ComponentTypeUse<'a, InstanceType<'a>>, |
203 | | }, |
204 | | /// Instantiate a component. |
205 | | Instantiate { |
206 | | /// The component being instantiated. |
207 | | component: ItemRef<'a, kw::component>, |
208 | | /// Arguments used to instantiate the instance. |
209 | | args: Vec<InstantiationArg<'a>>, |
210 | | }, |
211 | | /// The instance is defined by exporting local items as an instance. |
212 | | BundleOfExports(Vec<ComponentExport<'a>>), |
213 | | } |
214 | | |
215 | | impl<'a> Parse<'a> for InstanceKind<'a> { |
216 | 0 | fn parse(parser: Parser<'a>) -> Result<Self> { |
217 | 0 | if let Some(import) = parser.parse()? { |
218 | | return Ok(Self::Import { |
219 | 0 | import, |
220 | 0 | ty: parser.parse()?, |
221 | | }); |
222 | 0 | } |
223 | 0 |
|
224 | 0 | if parser.peek::<LParen>()? && parser.peek2::<kw::instantiate>()? { |
225 | 0 | parser.parens(|parser| { |
226 | 0 | parser.parse::<kw::instantiate>()?; |
227 | | Ok(Self::Instantiate { |
228 | 0 | component: parser.parse::<IndexOrRef<'_, _>>()?.0, |
229 | 0 | args: parser.parse()?, |
230 | | }) |
231 | 0 | }) |
232 | | } else { |
233 | 0 | Ok(Self::BundleOfExports(parser.parse()?)) |
234 | | } |
235 | 0 | } |
236 | | } |
237 | | |
238 | | impl Default for kw::component { |
239 | 0 | fn default() -> kw::component { |
240 | 0 | kw::component(Span::from_offset(0)) |
241 | 0 | } |
242 | | } |
243 | | |
244 | | /// An argument to instantiate a component. |
245 | | #[derive(Debug)] |
246 | | pub struct InstantiationArg<'a> { |
247 | | /// The name of the instantiation argument. |
248 | | pub name: &'a str, |
249 | | /// The kind of instantiation argument. |
250 | | pub kind: InstantiationArgKind<'a>, |
251 | | } |
252 | | |
253 | | impl<'a> Parse<'a> for InstantiationArg<'a> { |
254 | 0 | fn parse(parser: Parser<'a>) -> Result<Self> { |
255 | 0 | parser.parse::<kw::with>()?; |
256 | | Ok(Self { |
257 | 0 | name: parser.parse()?, |
258 | 0 | kind: parser.parse()?, |
259 | | }) |
260 | 0 | } |
261 | | } |
262 | | |
263 | | impl<'a> Parse<'a> for Vec<InstantiationArg<'a>> { |
264 | 0 | fn parse(parser: Parser<'a>) -> Result<Self> { |
265 | 0 | let mut args = Vec::new(); |
266 | 0 | while !parser.is_empty() { |
267 | 0 | args.push(parser.parens(|parser| parser.parse())?); |
268 | | } |
269 | 0 | Ok(args) |
270 | 0 | } |
271 | | } |
272 | | |
273 | | /// The kind of instantiation argument. |
274 | | #[derive(Debug)] |
275 | | pub enum InstantiationArgKind<'a> { |
276 | | /// The argument is a reference to a component item. |
277 | | Item(ComponentExportKind<'a>), |
278 | | /// The argument is an instance created from local exported items. |
279 | | /// |
280 | | /// This is syntactic sugar for defining an instance and also using it |
281 | | /// as an instantiation argument. |
282 | | BundleOfExports(Span, Vec<ComponentExport<'a>>), |
283 | | } |
284 | | |
285 | | impl<'a> Parse<'a> for InstantiationArgKind<'a> { |
286 | 0 | fn parse(parser: Parser<'a>) -> Result<Self> { |
287 | 0 | if let Some(item) = parser.parse()? { |
288 | 0 | Ok(Self::Item(item)) |
289 | | } else { |
290 | 0 | parser.parens(|parser| { |
291 | 0 | let span = parser.parse::<kw::instance>()?.0; |
292 | 0 | Ok(Self::BundleOfExports(span, parser.parse()?)) |
293 | 0 | }) |
294 | | } |
295 | 0 | } |
296 | | } |