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