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