1use crate::{encode_section, ComponentSection, ComponentSectionId, ComponentValType, Encode};
2use alloc::vec::Vec;
3
4#[derive(Debug, Clone, Copy, PartialEq, Eq)]
6pub enum CanonicalOption {
7 UTF8,
9 UTF16,
11 CompactUTF16,
13 Memory(u32),
17 Realloc(u32),
22 PostReturn(u32),
25 Async,
27 Callback(u32),
30}
31
32impl Encode for CanonicalOption {
33 fn encode(&self, sink: &mut Vec<u8>) {
34 match self {
35 Self::UTF8 => sink.push(0x00),
36 Self::UTF16 => sink.push(0x01),
37 Self::CompactUTF16 => sink.push(0x02),
38 Self::Memory(idx) => {
39 sink.push(0x03);
40 idx.encode(sink);
41 }
42 Self::Realloc(idx) => {
43 sink.push(0x04);
44 idx.encode(sink);
45 }
46 Self::PostReturn(idx) => {
47 sink.push(0x05);
48 idx.encode(sink);
49 }
50 Self::Async => {
51 sink.push(0x06);
52 }
53 Self::Callback(idx) => {
54 sink.push(0x07);
55 idx.encode(sink);
56 }
57 }
58 }
59}
60
61#[derive(Clone, Debug, Default)]
77pub struct CanonicalFunctionSection {
78 bytes: Vec<u8>,
79 num_added: u32,
80}
81
82impl CanonicalFunctionSection {
83 pub fn new() -> Self {
85 Self::default()
86 }
87
88 pub fn len(&self) -> u32 {
90 self.num_added
91 }
92
93 pub fn is_empty(&self) -> bool {
95 self.num_added == 0
96 }
97
98 pub fn lift<O>(&mut self, core_func_index: u32, type_index: u32, options: O) -> &mut Self
100 where
101 O: IntoIterator<Item = CanonicalOption>,
102 O::IntoIter: ExactSizeIterator,
103 {
104 self.bytes.push(0x00);
105 self.bytes.push(0x00);
106 core_func_index.encode(&mut self.bytes);
107 self.encode_options(options);
108 type_index.encode(&mut self.bytes);
109 self.num_added += 1;
110 self
111 }
112
113 pub fn lower<O>(&mut self, func_index: u32, options: O) -> &mut Self
115 where
116 O: IntoIterator<Item = CanonicalOption>,
117 O::IntoIter: ExactSizeIterator,
118 {
119 self.bytes.push(0x01);
120 self.bytes.push(0x00);
121 func_index.encode(&mut self.bytes);
122 self.encode_options(options);
123 self.num_added += 1;
124 self
125 }
126
127 pub fn resource_new(&mut self, ty_index: u32) -> &mut Self {
130 self.bytes.push(0x02);
131 ty_index.encode(&mut self.bytes);
132 self.num_added += 1;
133 self
134 }
135
136 pub fn resource_drop(&mut self, ty_index: u32) -> &mut Self {
138 self.bytes.push(0x03);
139 ty_index.encode(&mut self.bytes);
140 self.num_added += 1;
141 self
142 }
143
144 pub fn resource_drop_async(&mut self, ty_index: u32) -> &mut Self {
146 self.bytes.push(0x07);
147 ty_index.encode(&mut self.bytes);
148 self.num_added += 1;
149 self
150 }
151
152 pub fn resource_rep(&mut self, ty_index: u32) -> &mut Self {
155 self.bytes.push(0x04);
156 ty_index.encode(&mut self.bytes);
157 self.num_added += 1;
158 self
159 }
160
161 pub fn thread_spawn(&mut self, ty_index: u32) -> &mut Self {
164 self.bytes.push(0x05);
165 ty_index.encode(&mut self.bytes);
166 self.num_added += 1;
167 self
168 }
169
170 pub fn thread_available_parallelism(&mut self) -> &mut Self {
173 self.bytes.push(0x06);
174 self.num_added += 1;
175 self
176 }
177
178 pub fn backpressure_set(&mut self) -> &mut Self {
183 self.bytes.push(0x08);
184 self.num_added += 1;
185 self
186 }
187
188 pub fn task_return<O>(&mut self, ty: Option<ComponentValType>, options: O) -> &mut Self
192 where
193 O: IntoIterator<Item = CanonicalOption>,
194 O::IntoIter: ExactSizeIterator,
195 {
196 self.bytes.push(0x09);
197 crate::encode_resultlist(&mut self.bytes, ty);
198 self.encode_options(options);
199 self.num_added += 1;
200 self
201 }
202
203 pub fn yield_(&mut self, async_: bool) -> &mut Self {
208 self.bytes.push(0x0c);
209 self.bytes.push(if async_ { 1 } else { 0 });
210 self.num_added += 1;
211 self
212 }
213
214 pub fn subtask_drop(&mut self) -> &mut Self {
216 self.bytes.push(0x0d);
217 self.num_added += 1;
218 self
219 }
220
221 pub fn stream_new(&mut self, ty: u32) -> &mut Self {
224 self.bytes.push(0x0e);
225 ty.encode(&mut self.bytes);
226 self.num_added += 1;
227 self
228 }
229
230 pub fn stream_read<O>(&mut self, ty: u32, options: O) -> &mut Self
232 where
233 O: IntoIterator<Item = CanonicalOption>,
234 O::IntoIter: ExactSizeIterator,
235 {
236 self.bytes.push(0x0f);
237 ty.encode(&mut self.bytes);
238 self.encode_options(options);
239 self.num_added += 1;
240 self
241 }
242
243 pub fn stream_write<O>(&mut self, ty: u32, options: O) -> &mut Self
245 where
246 O: IntoIterator<Item = CanonicalOption>,
247 O::IntoIter: ExactSizeIterator,
248 {
249 self.bytes.push(0x10);
250 ty.encode(&mut self.bytes);
251 self.encode_options(options);
252 self.num_added += 1;
253 self
254 }
255
256 pub fn stream_cancel_read(&mut self, ty: u32, async_: bool) -> &mut Self {
259 self.bytes.push(0x11);
260 ty.encode(&mut self.bytes);
261 self.bytes.push(if async_ { 1 } else { 0 });
262 self.num_added += 1;
263 self
264 }
265
266 pub fn stream_cancel_write(&mut self, ty: u32, async_: bool) -> &mut Self {
269 self.bytes.push(0x12);
270 ty.encode(&mut self.bytes);
271 self.bytes.push(if async_ { 1 } else { 0 });
272 self.num_added += 1;
273 self
274 }
275
276 pub fn stream_close_readable(&mut self, ty: u32) -> &mut Self {
279 self.bytes.push(0x13);
280 ty.encode(&mut self.bytes);
281 self.num_added += 1;
282 self
283 }
284
285 pub fn stream_close_writable(&mut self, ty: u32) -> &mut Self {
288 self.bytes.push(0x14);
289 ty.encode(&mut self.bytes);
290 self.num_added += 1;
291 self
292 }
293
294 pub fn future_new(&mut self, ty: u32) -> &mut Self {
297 self.bytes.push(0x15);
298 ty.encode(&mut self.bytes);
299 self.num_added += 1;
300 self
301 }
302
303 pub fn future_read<O>(&mut self, ty: u32, options: O) -> &mut Self
305 where
306 O: IntoIterator<Item = CanonicalOption>,
307 O::IntoIter: ExactSizeIterator,
308 {
309 self.bytes.push(0x16);
310 ty.encode(&mut self.bytes);
311 self.encode_options(options);
312 self.num_added += 1;
313 self
314 }
315
316 pub fn future_write<O>(&mut self, ty: u32, options: O) -> &mut Self
318 where
319 O: IntoIterator<Item = CanonicalOption>,
320 O::IntoIter: ExactSizeIterator,
321 {
322 self.bytes.push(0x17);
323 ty.encode(&mut self.bytes);
324 self.encode_options(options);
325 self.num_added += 1;
326 self
327 }
328
329 pub fn future_cancel_read(&mut self, ty: u32, async_: bool) -> &mut Self {
332 self.bytes.push(0x18);
333 ty.encode(&mut self.bytes);
334 self.bytes.push(if async_ { 1 } else { 0 });
335 self.num_added += 1;
336 self
337 }
338
339 pub fn future_cancel_write(&mut self, ty: u32, async_: bool) -> &mut Self {
342 self.bytes.push(0x19);
343 ty.encode(&mut self.bytes);
344 self.bytes.push(if async_ { 1 } else { 0 });
345 self.num_added += 1;
346 self
347 }
348
349 pub fn future_close_readable(&mut self, ty: u32) -> &mut Self {
352 self.bytes.push(0x1a);
353 ty.encode(&mut self.bytes);
354 self.num_added += 1;
355 self
356 }
357
358 pub fn future_close_writable(&mut self, ty: u32) -> &mut Self {
361 self.bytes.push(0x1b);
362 ty.encode(&mut self.bytes);
363 self.num_added += 1;
364 self
365 }
366
367 pub fn error_context_new<O>(&mut self, options: O) -> &mut Self
370 where
371 O: IntoIterator<Item = CanonicalOption>,
372 O::IntoIter: ExactSizeIterator,
373 {
374 self.bytes.push(0x1c);
375 self.encode_options(options);
376 self.num_added += 1;
377 self
378 }
379
380 pub fn error_context_debug_message<O>(&mut self, options: O) -> &mut Self
386 where
387 O: IntoIterator<Item = CanonicalOption>,
388 O::IntoIter: ExactSizeIterator,
389 {
390 self.bytes.push(0x1d);
391 self.encode_options(options);
392 self.num_added += 1;
393 self
394 }
395
396 pub fn error_context_drop(&mut self) -> &mut Self {
398 self.bytes.push(0x1e);
399 self.num_added += 1;
400 self
401 }
402
403 pub fn waitable_set_new(&mut self) -> &mut Self {
406 self.bytes.push(0x1f);
407 self.num_added += 1;
408 self
409 }
410
411 pub fn waitable_set_wait(&mut self, async_: bool, memory: u32) -> &mut Self {
414 self.bytes.push(0x20);
415 self.bytes.push(if async_ { 1 } else { 0 });
416 memory.encode(&mut self.bytes);
417 self.num_added += 1;
418 self
419 }
420
421 pub fn waitable_set_poll(&mut self, async_: bool, memory: u32) -> &mut Self {
424 self.bytes.push(0x21);
425 self.bytes.push(if async_ { 1 } else { 0 });
426 memory.encode(&mut self.bytes);
427 self.num_added += 1;
428 self
429 }
430
431 pub fn waitable_set_drop(&mut self) -> &mut Self {
434 self.bytes.push(0x22);
435 self.num_added += 1;
436 self
437 }
438
439 pub fn waitable_join(&mut self) -> &mut Self {
442 self.bytes.push(0x23);
443 self.num_added += 1;
444 self
445 }
446
447 fn encode_options<O>(&mut self, options: O) -> &mut Self
448 where
449 O: IntoIterator<Item = CanonicalOption>,
450 O::IntoIter: ExactSizeIterator,
451 {
452 let options = options.into_iter();
453 options.len().encode(&mut self.bytes);
454 for option in options {
455 option.encode(&mut self.bytes);
456 }
457 self
458 }
459}
460
461impl Encode for CanonicalFunctionSection {
462 fn encode(&self, sink: &mut Vec<u8>) {
463 encode_section(sink, self.num_added, &self.bytes);
464 }
465}
466
467impl ComponentSection for CanonicalFunctionSection {
468 fn id(&self) -> u8 {
469 ComponentSectionId::CanonicalFunction.into()
470 }
471}