Next Generation WASM Microkernel Operating System
1use crate::component::*;
2use crate::core;
3use crate::core::EncodeOptions;
4use crate::token::{Id, NameAnnotation};
5use alloc::vec::Vec;
6use wasm_encoder::{
7 CanonicalFunctionSection, ComponentAliasSection, ComponentCoreTypeEncoder,
8 ComponentDefinedTypeEncoder, ComponentExportSection, ComponentImportSection,
9 ComponentInstanceSection, ComponentNameSection, ComponentSection, ComponentSectionId,
10 ComponentStartSection, ComponentTypeEncoder, ComponentTypeSection, CoreTypeSection,
11 InstanceSection, NameMap, NestedComponentSection, RawSection,
12};
13
14pub fn encode(component: &Component<'_>, options: &EncodeOptions) -> Vec<u8> {
15 match &component.kind {
16 ComponentKind::Text(fields) => {
17 encode_fields(&component.id, &component.name, fields, options).finish()
18 }
19 ComponentKind::Binary(bytes) => bytes.iter().flat_map(|b| b.iter().copied()).collect(),
20 }
21}
22
23fn encode_fields(
24 // TODO: use the id and name for a future names section
25 component_id: &Option<Id<'_>>,
26 component_name: &Option<NameAnnotation<'_>>,
27 fields: &[ComponentField<'_>],
28 options: &EncodeOptions,
29) -> wasm_encoder::Component {
30 let mut e = Encoder::default();
31
32 for field in fields {
33 match field {
34 ComponentField::CoreModule(m) => e.encode_core_module(m, options),
35 ComponentField::CoreInstance(i) => e.encode_core_instance(i),
36 ComponentField::CoreType(t) => e.encode_core_type(t),
37 ComponentField::CoreRec(t) => e.encode_core_rec(t),
38 ComponentField::Component(c) => e.encode_component(c, options),
39 ComponentField::Instance(i) => e.encode_instance(i),
40 ComponentField::Alias(a) => e.encode_alias(a),
41 ComponentField::Type(t) => e.encode_type(t),
42 ComponentField::CanonicalFunc(f) => e.encode_canonical_func(f),
43 ComponentField::CoreFunc(_) | ComponentField::Func(_) => {
44 unreachable!("should be expanded already")
45 }
46 ComponentField::Start(s) => e.encode_start(s),
47 ComponentField::Import(i) => e.encode_import(i),
48 ComponentField::Export(ex) => e.encode_export(ex),
49 ComponentField::Custom(c) => e.encode_custom(c),
50 ComponentField::Producers(c) => e.encode_producers(c),
51 }
52 }
53
54 e.flush(None);
55 e.encode_names(component_id, component_name);
56
57 e.component
58}
59
60fn encode_core_type(encoder: ComponentCoreTypeEncoder, ty: &CoreTypeDef) {
61 match ty {
62 CoreTypeDef::Def(def) => {
63 encoder.core().subtype(&def.to_subtype());
64 }
65 CoreTypeDef::Module(t) => {
66 encoder.module(&t.into());
67 }
68 }
69}
70
71fn encode_type(encoder: ComponentTypeEncoder, ty: &TypeDef) {
72 match ty {
73 TypeDef::Defined(t) => {
74 encode_defined_type(encoder.defined_type(), t);
75 }
76 TypeDef::Func(f) => {
77 let mut encoder = encoder.function();
78 encoder.params(f.params.iter().map(|p| (p.name, &p.ty)));
79
80 encoder.result(f.result.as_ref().map(|ty| ty.into()));
81 }
82 TypeDef::Component(c) => {
83 encoder.component(&c.into());
84 }
85 TypeDef::Instance(i) => {
86 encoder.instance(&i.into());
87 }
88 TypeDef::Resource(i) => {
89 let dtor = i.dtor.as_ref().map(|i| i.idx.into());
90 encoder.resource(i.rep.into(), dtor);
91 }
92 }
93}
94
95fn encode_defined_type(encoder: ComponentDefinedTypeEncoder, ty: &ComponentDefinedType) {
96 match ty {
97 ComponentDefinedType::Primitive(p) => encoder.primitive((*p).into()),
98 ComponentDefinedType::Record(r) => {
99 encoder.record(r.fields.iter().map(|f| (f.name, &f.ty)));
100 }
101 ComponentDefinedType::Variant(v) => {
102 encoder.variant(v.cases.iter().map(|c| {
103 (
104 c.name,
105 c.ty.as_ref().map(Into::into),
106 c.refines.as_ref().map(Into::into),
107 )
108 }));
109 }
110 ComponentDefinedType::List(l) => {
111 encoder.list(l.element.as_ref());
112 }
113 ComponentDefinedType::Tuple(t) => {
114 encoder.tuple(t.fields.iter());
115 }
116 ComponentDefinedType::Flags(f) => {
117 encoder.flags(f.names.iter().copied());
118 }
119 ComponentDefinedType::Enum(e) => {
120 encoder.enum_type(e.names.iter().copied());
121 }
122 ComponentDefinedType::Option(o) => {
123 encoder.option(o.element.as_ref());
124 }
125 ComponentDefinedType::Result(e) => {
126 encoder.result(
127 e.ok.as_deref().map(Into::into),
128 e.err.as_deref().map(Into::into),
129 );
130 }
131 ComponentDefinedType::Own(i) => encoder.own((*i).into()),
132 ComponentDefinedType::Borrow(i) => encoder.borrow((*i).into()),
133 ComponentDefinedType::Stream(s) => encoder.stream(s.element.as_deref().map(Into::into)),
134 ComponentDefinedType::Future(f) => encoder.future(f.element.as_deref().map(Into::into)),
135 }
136}
137
138#[derive(Default)]
139struct Encoder<'a> {
140 component: wasm_encoder::Component,
141 current_section_id: Option<u8>,
142
143 // Core sections
144 // Note: module sections are written immediately
145 core_instances: InstanceSection,
146 core_types: CoreTypeSection,
147
148 // Component sections
149 // Note: custom, component, start sections are written immediately
150 instances: ComponentInstanceSection,
151 aliases: ComponentAliasSection,
152 types: ComponentTypeSection,
153 funcs: CanonicalFunctionSection,
154 imports: ComponentImportSection,
155 exports: ComponentExportSection,
156
157 core_func_names: Vec<Option<&'a str>>,
158 core_table_names: Vec<Option<&'a str>>,
159 core_memory_names: Vec<Option<&'a str>>,
160 core_global_names: Vec<Option<&'a str>>,
161 core_type_names: Vec<Option<&'a str>>,
162 core_module_names: Vec<Option<&'a str>>,
163 core_instance_names: Vec<Option<&'a str>>,
164 core_tag_names: Vec<Option<&'a str>>,
165 func_names: Vec<Option<&'a str>>,
166 value_names: Vec<Option<&'a str>>,
167 type_names: Vec<Option<&'a str>>,
168 component_names: Vec<Option<&'a str>>,
169 instance_names: Vec<Option<&'a str>>,
170}
171
172impl<'a> Encoder<'a> {
173 fn encode_custom(&mut self, custom: &Custom) {
174 // Flush any in-progress section before encoding the customs section
175 self.flush(None);
176 self.component.section(&custom.to_section());
177 }
178
179 fn encode_producers(&mut self, custom: &core::Producers) {
180 self.flush(None);
181 self.component.section(&custom.to_section());
182 }
183
184 fn encode_core_module(&mut self, module: &CoreModule<'a>, options: &EncodeOptions) {
185 // Flush any in-progress section before encoding the module
186 self.flush(None);
187
188 self.core_module_names
189 .push(get_name(&module.id, &module.name));
190
191 match &module.kind {
192 CoreModuleKind::Import { .. } => unreachable!("should be expanded already"),
193 CoreModuleKind::Inline { fields } => {
194 // TODO: replace this with a wasm-encoder based encoding (should return `wasm_encoder::Module`)
195 let data = crate::core::binary::encode(&module.id, &module.name, fields, options);
196 self.component.section(&RawSection {
197 id: ComponentSectionId::CoreModule.into(),
198 data: &data,
199 });
200 }
201 }
202 }
203
204 fn encode_core_instance(&mut self, instance: &CoreInstance<'a>) {
205 self.core_instance_names
206 .push(get_name(&instance.id, &instance.name));
207 match &instance.kind {
208 CoreInstanceKind::Instantiate { module, args } => {
209 self.core_instances.instantiate(
210 module.into(),
211 args.iter().map(|arg| (arg.name, (&arg.kind).into())),
212 );
213 }
214 CoreInstanceKind::BundleOfExports(exports) => {
215 self.core_instances.export_items(exports.iter().map(|e| {
216 let (kind, index) = (&e.item).into();
217 (e.name, kind, index)
218 }));
219 }
220 }
221
222 self.flush(Some(self.core_instances.id()));
223 }
224
225 fn encode_core_type(&mut self, ty: &CoreType<'a>) {
226 self.core_type_names.push(get_name(&ty.id, &ty.name));
227 encode_core_type(self.core_types.ty(), &ty.def);
228 self.flush(Some(self.core_types.id()));
229 }
230
231 fn encode_core_rec(&mut self, ty: &core::Rec<'a>) {
232 for ty in ty.types.iter() {
233 self.core_type_names.push(get_name(&ty.id, &ty.name));
234 }
235 self.core_types
236 .ty()
237 .core()
238 .rec(ty.types.iter().map(|t| t.to_subtype()));
239 self.flush(Some(self.core_types.id()));
240 }
241
242 fn encode_component(&mut self, component: &NestedComponent<'a>, options: &EncodeOptions) {
243 self.component_names
244 .push(get_name(&component.id, &component.name));
245 // Flush any in-progress section before encoding the component
246 self.flush(None);
247
248 match &component.kind {
249 NestedComponentKind::Import { .. } => unreachable!("should be expanded already"),
250 NestedComponentKind::Inline(fields) => {
251 self.component
252 .section(&NestedComponentSection(&encode_fields(
253 &component.id,
254 &component.name,
255 fields,
256 options,
257 )));
258 }
259 }
260 }
261
262 fn encode_instance(&mut self, instance: &Instance<'a>) {
263 self.instance_names
264 .push(get_name(&instance.id, &instance.name));
265 match &instance.kind {
266 InstanceKind::Import { .. } => unreachable!("should be expanded already"),
267 InstanceKind::Instantiate { component, args } => {
268 self.instances.instantiate(
269 component.into(),
270 args.iter().map(|arg| {
271 let (kind, index) = (&arg.kind).into();
272 (arg.name, kind, index)
273 }),
274 );
275 }
276 InstanceKind::BundleOfExports(exports) => {
277 self.instances.export_items(exports.iter().map(|e| {
278 let (kind, index) = (&e.kind).into();
279 (e.name.0, kind, index)
280 }));
281 }
282 }
283
284 self.flush(Some(self.instances.id()));
285 }
286
287 fn encode_alias(&mut self, alias: &Alias<'a>) {
288 let name = get_name(&alias.id, &alias.name);
289 self.aliases.alias((&alias.target).into());
290 match &alias.target {
291 AliasTarget::Export { kind, .. } => {
292 self.names_for_component_export_alias(*kind).push(name);
293 }
294 AliasTarget::CoreExport { kind, .. } => {
295 self.names_for_core_export_alias(*kind).push(name);
296 }
297 AliasTarget::Outer { kind, .. } => {
298 self.names_for_component_outer_alias(*kind).push(name);
299 }
300 }
301
302 self.flush(Some(self.aliases.id()));
303 }
304
305 fn encode_start(&mut self, start: &Start) {
306 // Flush any in-progress section before encoding the start section
307 self.flush(None);
308
309 self.component.section(&ComponentStartSection {
310 function_index: start.func.into(),
311 args: start.args.iter().map(|a| a.idx.into()).collect::<Vec<_>>(),
312 results: start.results.len() as u32,
313 });
314 }
315
316 fn encode_type(&mut self, ty: &Type<'a>) {
317 self.type_names.push(get_name(&ty.id, &ty.name));
318 encode_type(self.types.ty(), &ty.def);
319 self.flush(Some(self.types.id()));
320 }
321
322 fn encode_canonical_func(&mut self, func: &CanonicalFunc<'a>) {
323 let name = get_name(&func.id, &func.name);
324 match &func.kind {
325 CanonicalFuncKind::Lift { ty, info } => {
326 self.func_names.push(name);
327 self.funcs.lift(
328 info.func.idx.into(),
329 ty.into(),
330 info.opts.iter().map(Into::into),
331 );
332 }
333 CanonicalFuncKind::Core(core) => match core {
334 CoreFuncKind::Alias(_) => {
335 panic!("should have been removed during expansion")
336 }
337 CoreFuncKind::Lower(info) => {
338 self.core_func_names.push(name);
339 self.funcs
340 .lower(info.func.idx.into(), info.opts.iter().map(Into::into));
341 }
342 CoreFuncKind::ResourceNew(info) => {
343 self.core_func_names.push(name);
344 self.funcs.resource_new(info.ty.into());
345 }
346 CoreFuncKind::ResourceDrop(info) => {
347 self.core_func_names.push(name);
348 if info.async_ {
349 self.funcs.resource_drop_async(info.ty.into());
350 } else {
351 self.funcs.resource_drop(info.ty.into());
352 }
353 }
354 CoreFuncKind::ResourceRep(info) => {
355 self.core_func_names.push(name);
356 self.funcs.resource_rep(info.ty.into());
357 }
358 CoreFuncKind::ThreadSpawnRef(info) => {
359 self.core_func_names.push(name);
360 self.funcs.thread_spawn_ref(info.ty.into());
361 }
362 CoreFuncKind::ThreadSpawnIndirect(info) => {
363 self.core_func_names.push(name);
364 self.funcs
365 .thread_spawn_indirect(info.ty.into(), info.table.idx.into());
366 }
367 CoreFuncKind::ThreadAvailableParallelism(_info) => {
368 self.core_func_names.push(name);
369 self.funcs.thread_available_parallelism();
370 }
371 CoreFuncKind::BackpressureSet => {
372 self.core_func_names.push(name);
373 self.funcs.backpressure_set();
374 }
375 CoreFuncKind::TaskReturn(info) => {
376 self.core_func_names.push(name);
377 self.funcs.task_return(
378 info.result
379 .as_ref()
380 .map(|ty| wasm_encoder::ComponentValType::from(ty)),
381 info.opts.iter().map(Into::into),
382 );
383 }
384 CoreFuncKind::ContextGet(i) => {
385 self.core_func_names.push(name);
386 self.funcs.context_get(*i);
387 }
388 CoreFuncKind::ContextSet(i) => {
389 self.core_func_names.push(name);
390 self.funcs.context_set(*i);
391 }
392 CoreFuncKind::Yield(info) => {
393 self.core_func_names.push(name);
394 self.funcs.yield_(info.async_);
395 }
396 CoreFuncKind::SubtaskDrop => {
397 self.core_func_names.push(name);
398 self.funcs.subtask_drop();
399 }
400 CoreFuncKind::StreamNew(info) => {
401 self.core_func_names.push(name);
402 self.funcs.stream_new(info.ty.into());
403 }
404 CoreFuncKind::StreamRead(info) => {
405 self.core_func_names.push(name);
406 self.funcs
407 .stream_read(info.ty.into(), info.opts.iter().map(Into::into));
408 }
409 CoreFuncKind::StreamWrite(info) => {
410 self.core_func_names.push(name);
411 self.funcs
412 .stream_write(info.ty.into(), info.opts.iter().map(Into::into));
413 }
414 CoreFuncKind::StreamCancelRead(info) => {
415 self.core_func_names.push(name);
416 self.funcs.stream_cancel_read(info.ty.into(), info.async_);
417 }
418 CoreFuncKind::StreamCancelWrite(info) => {
419 self.core_func_names.push(name);
420 self.funcs.stream_cancel_write(info.ty.into(), info.async_);
421 }
422 CoreFuncKind::StreamCloseReadable(info) => {
423 self.core_func_names.push(name);
424 self.funcs.stream_close_readable(info.ty.into());
425 }
426 CoreFuncKind::StreamCloseWritable(info) => {
427 self.core_func_names.push(name);
428 self.funcs.stream_close_writable(info.ty.into());
429 }
430 CoreFuncKind::FutureNew(info) => {
431 self.core_func_names.push(name);
432 self.funcs.future_new(info.ty.into());
433 }
434 CoreFuncKind::FutureRead(info) => {
435 self.core_func_names.push(name);
436 self.funcs
437 .future_read(info.ty.into(), info.opts.iter().map(Into::into));
438 }
439 CoreFuncKind::FutureWrite(info) => {
440 self.core_func_names.push(name);
441 self.funcs
442 .future_write(info.ty.into(), info.opts.iter().map(Into::into));
443 }
444 CoreFuncKind::FutureCancelRead(info) => {
445 self.core_func_names.push(name);
446 self.funcs.future_cancel_read(info.ty.into(), info.async_);
447 }
448 CoreFuncKind::FutureCancelWrite(info) => {
449 self.core_func_names.push(name);
450 self.funcs.future_cancel_write(info.ty.into(), info.async_);
451 }
452 CoreFuncKind::FutureCloseReadable(info) => {
453 self.core_func_names.push(name);
454 self.funcs.future_close_readable(info.ty.into());
455 }
456 CoreFuncKind::FutureCloseWritable(info) => {
457 self.core_func_names.push(name);
458 self.funcs.future_close_writable(info.ty.into());
459 }
460 CoreFuncKind::ErrorContextNew(info) => {
461 self.core_func_names.push(name);
462 self.funcs
463 .error_context_new(info.opts.iter().map(Into::into));
464 }
465 CoreFuncKind::ErrorContextDebugMessage(info) => {
466 self.core_func_names.push(name);
467 self.funcs
468 .error_context_debug_message(info.opts.iter().map(Into::into));
469 }
470 CoreFuncKind::ErrorContextDrop => {
471 self.core_func_names.push(name);
472 self.funcs.error_context_drop();
473 }
474 CoreFuncKind::WaitableSetNew => {
475 self.core_func_names.push(name);
476 self.funcs.waitable_set_new();
477 }
478 CoreFuncKind::WaitableSetWait(info) => {
479 self.core_func_names.push(name);
480 self.funcs
481 .waitable_set_wait(info.async_, info.memory.idx.into());
482 }
483 CoreFuncKind::WaitableSetPoll(info) => {
484 self.core_func_names.push(name);
485 self.funcs
486 .waitable_set_poll(info.async_, info.memory.idx.into());
487 }
488 CoreFuncKind::WaitableSetDrop => {
489 self.core_func_names.push(name);
490 self.funcs.waitable_set_drop();
491 }
492 CoreFuncKind::WaitableJoin => {
493 self.core_func_names.push(name);
494 self.funcs.waitable_join();
495 }
496 },
497 }
498
499 self.flush(Some(self.funcs.id()));
500 }
501
502 fn encode_import(&mut self, import: &ComponentImport<'a>) {
503 let name = get_name(&import.item.id, &import.item.name);
504 self.names_for_item_kind(&import.item.kind).push(name);
505 self.imports
506 .import(import.name.0, (&import.item.kind).into());
507 self.flush(Some(self.imports.id()));
508 }
509
510 fn encode_export(&mut self, export: &ComponentExport<'a>) {
511 let name = get_name(&export.id, &export.debug_name);
512 let (kind, index) = (&export.kind).into();
513 self.exports.export(
514 export.name.0,
515 kind,
516 index,
517 export.ty.as_ref().map(|ty| (&ty.0.kind).into()),
518 );
519 match &export.kind {
520 ComponentExportKind::CoreModule(_) => self.core_module_names.push(name),
521 ComponentExportKind::Func(_) => self.func_names.push(name),
522 ComponentExportKind::Instance(_) => self.instance_names.push(name),
523 ComponentExportKind::Value(_) => self.value_names.push(name),
524 ComponentExportKind::Component(_) => self.component_names.push(name),
525 ComponentExportKind::Type(_) => self.type_names.push(name),
526 }
527 self.flush(Some(self.exports.id()));
528 }
529
530 fn flush(&mut self, section_id: Option<u8>) {
531 if self.current_section_id == section_id {
532 return;
533 }
534
535 if let Some(id) = self.current_section_id {
536 match id {
537 // 0 => custom sections are written immediately
538 // 1 => core modules sections are written immediately
539 2 => {
540 assert_eq!(id, self.core_instances.id());
541 self.component.section(&self.core_instances);
542 self.core_instances = Default::default();
543 }
544 3 => {
545 assert_eq!(id, self.core_types.id());
546 self.component.section(&self.core_types);
547 self.core_types = Default::default();
548 }
549 // 4 => components sections are written immediately
550 5 => {
551 assert_eq!(id, self.instances.id());
552 self.component.section(&self.instances);
553 self.instances = Default::default();
554 }
555 6 => {
556 assert_eq!(id, self.aliases.id());
557 self.component.section(&self.aliases);
558 self.aliases = Default::default();
559 }
560 7 => {
561 assert_eq!(id, self.types.id());
562 self.component.section(&self.types);
563 self.types = Default::default();
564 }
565 8 => {
566 assert_eq!(id, self.funcs.id());
567 self.component.section(&self.funcs);
568 self.funcs = Default::default();
569 }
570 // 9 => start sections are written immediately
571 10 => {
572 assert_eq!(id, self.imports.id());
573 self.component.section(&self.imports);
574 self.imports = Default::default();
575 }
576 11 => {
577 assert_eq!(id, self.exports.id());
578 self.component.section(&self.exports);
579 self.exports = Default::default();
580 }
581 _ => unreachable!("unknown incremental component section id: {}", id),
582 }
583 }
584
585 self.current_section_id = section_id
586 }
587
588 fn encode_names(
589 &mut self,
590 component_id: &Option<Id<'_>>,
591 component_name: &Option<NameAnnotation<'_>>,
592 ) {
593 let mut names = ComponentNameSection::new();
594 if let Some(name) = get_name(component_id, component_name) {
595 names.component(name);
596 }
597
598 let mut funcs = |list: &[Option<&str>], append: fn(&mut ComponentNameSection, &NameMap)| {
599 let mut map = NameMap::new();
600 for (i, entry) in list.iter().enumerate() {
601 if let Some(name) = entry {
602 map.append(i as u32, name);
603 }
604 }
605 if !map.is_empty() {
606 append(&mut names, &map);
607 }
608 };
609
610 funcs(&self.core_func_names, ComponentNameSection::core_funcs);
611 funcs(&self.core_table_names, ComponentNameSection::core_tables);
612 funcs(&self.core_memory_names, ComponentNameSection::core_memories);
613 funcs(&self.core_global_names, ComponentNameSection::core_globals);
614 funcs(&self.core_tag_names, ComponentNameSection::core_tags);
615 funcs(&self.core_type_names, ComponentNameSection::core_types);
616 funcs(&self.core_module_names, ComponentNameSection::core_modules);
617 funcs(
618 &self.core_instance_names,
619 ComponentNameSection::core_instances,
620 );
621 funcs(&self.func_names, ComponentNameSection::funcs);
622 funcs(&self.value_names, ComponentNameSection::values);
623 funcs(&self.type_names, ComponentNameSection::types);
624 funcs(&self.component_names, ComponentNameSection::components);
625 funcs(&self.instance_names, ComponentNameSection::instances);
626
627 if !names.is_empty() {
628 self.component.section(&names);
629 }
630 }
631
632 fn names_for_component_export_alias(
633 &mut self,
634 kind: ComponentExportAliasKind,
635 ) -> &mut Vec<Option<&'a str>> {
636 match kind {
637 ComponentExportAliasKind::Func => &mut self.func_names,
638 ComponentExportAliasKind::CoreModule => &mut self.core_module_names,
639 ComponentExportAliasKind::Value => &mut self.value_names,
640 ComponentExportAliasKind::Type => &mut self.type_names,
641 ComponentExportAliasKind::Component => &mut self.component_names,
642 ComponentExportAliasKind::Instance => &mut self.instance_names,
643 }
644 }
645
646 fn names_for_component_outer_alias(
647 &mut self,
648 kind: ComponentOuterAliasKind,
649 ) -> &mut Vec<Option<&'a str>> {
650 match kind {
651 ComponentOuterAliasKind::CoreModule => &mut self.core_module_names,
652 ComponentOuterAliasKind::CoreType => &mut self.core_type_names,
653 ComponentOuterAliasKind::Component => &mut self.component_names,
654 ComponentOuterAliasKind::Type => &mut self.type_names,
655 }
656 }
657
658 fn names_for_core_export_alias(&mut self, kind: core::ExportKind) -> &mut Vec<Option<&'a str>> {
659 match kind {
660 core::ExportKind::Func => &mut self.core_func_names,
661 core::ExportKind::Global => &mut self.core_global_names,
662 core::ExportKind::Table => &mut self.core_table_names,
663 core::ExportKind::Memory => &mut self.core_memory_names,
664 core::ExportKind::Tag => &mut self.core_tag_names,
665 }
666 }
667
668 fn names_for_item_kind(&mut self, kind: &ItemSigKind) -> &mut Vec<Option<&'a str>> {
669 match kind {
670 ItemSigKind::CoreModule(_) => &mut self.core_module_names,
671 ItemSigKind::Func(_) => &mut self.func_names,
672 ItemSigKind::Component(_) => &mut self.component_names,
673 ItemSigKind::Instance(_) => &mut self.instance_names,
674 ItemSigKind::Value(_) => &mut self.value_names,
675 ItemSigKind::Type(_) => &mut self.type_names,
676 }
677 }
678}
679
680fn get_name<'a>(id: &Option<Id<'a>>, name: &Option<NameAnnotation<'a>>) -> Option<&'a str> {
681 name.as_ref().map(|n| n.name).or_else(|| {
682 id.and_then(|id| {
683 if id.is_gensym() {
684 None
685 } else {
686 Some(id.name())
687 }
688 })
689 })
690}
691
692impl Custom<'_> {
693 fn to_section(&self) -> wasm_encoder::CustomSection<'_> {
694 let mut ret = Vec::new();
695 for list in self.data.iter() {
696 ret.extend_from_slice(list);
697 }
698 wasm_encoder::CustomSection {
699 name: self.name.into(),
700 data: ret.into(),
701 }
702 }
703}
704
705impl From<&CoreInstantiationArgKind<'_>> for wasm_encoder::ModuleArg {
706 fn from(kind: &CoreInstantiationArgKind) -> Self {
707 match kind {
708 CoreInstantiationArgKind::Instance(i) => {
709 wasm_encoder::ModuleArg::Instance(i.idx.into())
710 }
711 CoreInstantiationArgKind::BundleOfExports(..) => {
712 unreachable!("should be expanded already")
713 }
714 }
715 }
716}
717
718impl From<&CoreItemRef<'_, core::ExportKind>> for (wasm_encoder::ExportKind, u32) {
719 fn from(item: &CoreItemRef<'_, core::ExportKind>) -> Self {
720 match &item.kind {
721 core::ExportKind::Func => (wasm_encoder::ExportKind::Func, item.idx.into()),
722 core::ExportKind::Table => (wasm_encoder::ExportKind::Table, item.idx.into()),
723 core::ExportKind::Memory => (wasm_encoder::ExportKind::Memory, item.idx.into()),
724 core::ExportKind::Global => (wasm_encoder::ExportKind::Global, item.idx.into()),
725 core::ExportKind::Tag => (wasm_encoder::ExportKind::Tag, item.idx.into()),
726 }
727 }
728}
729
730impl<T> From<&ItemRef<'_, T>> for u32 {
731 fn from(i: &ItemRef<'_, T>) -> Self {
732 assert!(i.export_names.is_empty());
733 i.idx.into()
734 }
735}
736
737impl<T> From<&CoreTypeUse<'_, T>> for u32 {
738 fn from(u: &CoreTypeUse<'_, T>) -> Self {
739 match u {
740 CoreTypeUse::Inline(_) => unreachable!("should be expanded already"),
741 CoreTypeUse::Ref(r) => r.idx.into(),
742 }
743 }
744}
745
746impl<T> From<&ComponentTypeUse<'_, T>> for u32 {
747 fn from(u: &ComponentTypeUse<'_, T>) -> Self {
748 match u {
749 ComponentTypeUse::Inline(_) => unreachable!("should be expanded already"),
750 ComponentTypeUse::Ref(r) => r.idx.into(),
751 }
752 }
753}
754
755impl From<&ComponentValType<'_>> for wasm_encoder::ComponentValType {
756 fn from(r: &ComponentValType) -> Self {
757 match r {
758 ComponentValType::Inline(ComponentDefinedType::Primitive(p)) => {
759 Self::Primitive((*p).into())
760 }
761 ComponentValType::Ref(i) => Self::Type(u32::from(*i)),
762 ComponentValType::Inline(_) => unreachable!("should be expanded by now"),
763 }
764 }
765}
766
767impl From<PrimitiveValType> for wasm_encoder::PrimitiveValType {
768 fn from(p: PrimitiveValType) -> Self {
769 match p {
770 PrimitiveValType::Bool => Self::Bool,
771 PrimitiveValType::S8 => Self::S8,
772 PrimitiveValType::U8 => Self::U8,
773 PrimitiveValType::S16 => Self::S16,
774 PrimitiveValType::U16 => Self::U16,
775 PrimitiveValType::S32 => Self::S32,
776 PrimitiveValType::U32 => Self::U32,
777 PrimitiveValType::S64 => Self::S64,
778 PrimitiveValType::U64 => Self::U64,
779 PrimitiveValType::F32 => Self::F32,
780 PrimitiveValType::F64 => Self::F64,
781 PrimitiveValType::Char => Self::Char,
782 PrimitiveValType::String => Self::String,
783 PrimitiveValType::ErrorContext => Self::ErrorContext,
784 }
785 }
786}
787
788impl From<&Refinement<'_>> for u32 {
789 fn from(r: &Refinement) -> Self {
790 match r {
791 Refinement::Index(..) => unreachable!("should be resolved by now"),
792 Refinement::Resolved(i) => *i,
793 }
794 }
795}
796
797impl From<&ItemSigKind<'_>> for wasm_encoder::ComponentTypeRef {
798 fn from(k: &ItemSigKind) -> Self {
799 match k {
800 ItemSigKind::Component(c) => Self::Component(c.into()),
801 ItemSigKind::CoreModule(m) => Self::Module(m.into()),
802 ItemSigKind::Instance(i) => Self::Instance(i.into()),
803 ItemSigKind::Value(v) => Self::Value((&v.0).into()),
804 ItemSigKind::Func(f) => Self::Func(f.into()),
805 ItemSigKind::Type(TypeBounds::Eq(t)) => {
806 Self::Type(wasm_encoder::TypeBounds::Eq((*t).into()))
807 }
808 ItemSigKind::Type(TypeBounds::SubResource) => {
809 Self::Type(wasm_encoder::TypeBounds::SubResource)
810 }
811 }
812 }
813}
814
815impl From<&ComponentType<'_>> for wasm_encoder::ComponentType {
816 fn from(ty: &ComponentType) -> Self {
817 let mut encoded = wasm_encoder::ComponentType::new();
818
819 for decl in &ty.decls {
820 match decl {
821 ComponentTypeDecl::CoreType(t) => {
822 encode_core_type(encoded.core_type(), &t.def);
823 }
824 ComponentTypeDecl::Type(t) => {
825 encode_type(encoded.ty(), &t.def);
826 }
827 ComponentTypeDecl::Alias(a) => {
828 encoded.alias((&a.target).into());
829 }
830 ComponentTypeDecl::Import(i) => {
831 encoded.import(i.name.0, (&i.item.kind).into());
832 }
833 ComponentTypeDecl::Export(e) => {
834 encoded.export(e.name.0, (&e.item.kind).into());
835 }
836 }
837 }
838
839 encoded
840 }
841}
842
843impl From<&InstanceType<'_>> for wasm_encoder::InstanceType {
844 fn from(ty: &InstanceType) -> Self {
845 let mut encoded = wasm_encoder::InstanceType::new();
846
847 for decl in &ty.decls {
848 match decl {
849 InstanceTypeDecl::CoreType(t) => {
850 encode_core_type(encoded.core_type(), &t.def);
851 }
852 InstanceTypeDecl::Type(t) => {
853 encode_type(encoded.ty(), &t.def);
854 }
855 InstanceTypeDecl::Alias(a) => {
856 encoded.alias((&a.target).into());
857 }
858 InstanceTypeDecl::Export(e) => {
859 encoded.export(e.name.0, (&e.item.kind).into());
860 }
861 }
862 }
863
864 encoded
865 }
866}
867
868impl From<&ModuleType<'_>> for wasm_encoder::ModuleType {
869 fn from(ty: &ModuleType) -> Self {
870 let mut encoded = wasm_encoder::ModuleType::new();
871
872 for decl in &ty.decls {
873 match decl {
874 ModuleTypeDecl::Type(t) => {
875 encoded.ty().subtype(&t.to_subtype());
876 }
877 ModuleTypeDecl::Rec(rec) => {
878 encoded.ty().rec(rec.types.iter().map(|t| t.to_subtype()));
879 }
880 ModuleTypeDecl::Alias(a) => match &a.target {
881 AliasTarget::Outer {
882 outer,
883 index,
884 kind: ComponentOuterAliasKind::CoreType,
885 } => {
886 encoded.alias_outer_core_type(u32::from(*outer), u32::from(*index));
887 }
888 _ => unreachable!("only outer type aliases are supported"),
889 },
890 ModuleTypeDecl::Import(i) => {
891 encoded.import(i.module, i.field, i.item.to_entity_type());
892 }
893 ModuleTypeDecl::Export(name, item) => {
894 encoded.export(name, item.to_entity_type());
895 }
896 }
897 }
898
899 encoded
900 }
901}
902
903impl From<&InstantiationArgKind<'_>> for (wasm_encoder::ComponentExportKind, u32) {
904 fn from(kind: &InstantiationArgKind) -> Self {
905 match kind {
906 InstantiationArgKind::Item(i) => i.into(),
907 InstantiationArgKind::BundleOfExports(..) => unreachable!("should be expanded already"),
908 }
909 }
910}
911
912impl From<&ComponentExportKind<'_>> for (wasm_encoder::ComponentExportKind, u32) {
913 fn from(kind: &ComponentExportKind) -> Self {
914 match kind {
915 ComponentExportKind::CoreModule(m) => {
916 (wasm_encoder::ComponentExportKind::Module, m.idx.into())
917 }
918 ComponentExportKind::Func(f) => (wasm_encoder::ComponentExportKind::Func, f.idx.into()),
919 ComponentExportKind::Value(v) => {
920 (wasm_encoder::ComponentExportKind::Value, v.idx.into())
921 }
922 ComponentExportKind::Type(t) => (wasm_encoder::ComponentExportKind::Type, t.idx.into()),
923 ComponentExportKind::Component(c) => {
924 (wasm_encoder::ComponentExportKind::Component, c.idx.into())
925 }
926 ComponentExportKind::Instance(i) => {
927 (wasm_encoder::ComponentExportKind::Instance, i.idx.into())
928 }
929 }
930 }
931}
932
933impl From<ComponentOuterAliasKind> for wasm_encoder::ComponentOuterAliasKind {
934 fn from(kind: ComponentOuterAliasKind) -> Self {
935 match kind {
936 ComponentOuterAliasKind::CoreModule => Self::CoreModule,
937 ComponentOuterAliasKind::CoreType => Self::CoreType,
938 ComponentOuterAliasKind::Type => Self::Type,
939 ComponentOuterAliasKind::Component => Self::Component,
940 }
941 }
942}
943
944impl From<ComponentExportAliasKind> for wasm_encoder::ComponentExportKind {
945 fn from(kind: ComponentExportAliasKind) -> Self {
946 match kind {
947 ComponentExportAliasKind::CoreModule => Self::Module,
948 ComponentExportAliasKind::Func => Self::Func,
949 ComponentExportAliasKind::Value => Self::Value,
950 ComponentExportAliasKind::Type => Self::Type,
951 ComponentExportAliasKind::Component => Self::Component,
952 ComponentExportAliasKind::Instance => Self::Instance,
953 }
954 }
955}
956
957impl From<&CanonOpt<'_>> for wasm_encoder::CanonicalOption {
958 fn from(opt: &CanonOpt) -> Self {
959 match opt {
960 CanonOpt::StringUtf8 => Self::UTF8,
961 CanonOpt::StringUtf16 => Self::UTF16,
962 CanonOpt::StringLatin1Utf16 => Self::CompactUTF16,
963 CanonOpt::Memory(m) => Self::Memory(m.idx.into()),
964 CanonOpt::Realloc(f) => Self::Realloc(f.idx.into()),
965 CanonOpt::PostReturn(f) => Self::PostReturn(f.idx.into()),
966 CanonOpt::Async => Self::Async,
967 CanonOpt::Callback(f) => Self::Callback(f.idx.into()),
968 }
969 }
970}
971
972impl<'a> From<&AliasTarget<'a>> for wasm_encoder::Alias<'a> {
973 fn from(target: &AliasTarget<'a>) -> Self {
974 match target {
975 AliasTarget::Export {
976 instance,
977 name,
978 kind,
979 } => wasm_encoder::Alias::InstanceExport {
980 instance: (*instance).into(),
981 kind: (*kind).into(),
982 name,
983 },
984 AliasTarget::CoreExport {
985 instance,
986 name,
987 kind,
988 } => wasm_encoder::Alias::CoreInstanceExport {
989 instance: (*instance).into(),
990 kind: (*kind).into(),
991 name,
992 },
993 AliasTarget::Outer { outer, index, kind } => wasm_encoder::Alias::Outer {
994 count: (*outer).into(),
995 kind: (*kind).into(),
996 index: (*index).into(),
997 },
998 }
999 }
1000}