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: &Vec>) => {
16 encode_fields(&component.id, &component.name, fields, options).finish()
17 }
18 ComponentKind::Binary(bytes: &Vec<&[u8]>) => bytes.iter().flat_map(|b: &&[u8]| b.iter().copied()).collect(),
19 }
20}
21
22fn encode_fields(
23 // TODO: use the id and name for a future names section
24 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: &TypeDef<'_>) => {
62 encoder.core().subtype(&def.to_subtype());
63 }
64 CoreTypeDef::Module(t: &ModuleType<'_>) => {
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 if f.results.len() == 1 && f.results[0].name.is_none() {
80 encoder.result(&f.results[0].ty);
81 } else {
82 encoder.results(f.results.iter().map(|r| (r.name.unwrap_or(""), &r.ty)));
83 }
84 }
85 TypeDef::Component(c) => {
86 encoder.component(&c.into());
87 }
88 TypeDef::Instance(i) => {
89 encoder.instance(&i.into());
90 }
91 TypeDef::Resource(i) => {
92 let dtor = i.dtor.as_ref().map(|i| i.idx.into());
93 encoder.resource(i.rep.into(), dtor);
94 }
95 }
96}
97
98fn encode_defined_type(encoder: ComponentDefinedTypeEncoder, ty: &ComponentDefinedType) {
99 match ty {
100 ComponentDefinedType::Primitive(p) => encoder.primitive((*p).into()),
101 ComponentDefinedType::Record(r) => {
102 encoder.record(r.fields.iter().map(|f| (f.name, &f.ty)));
103 }
104 ComponentDefinedType::Variant(v) => {
105 encoder.variant(v.cases.iter().map(|c| {
106 (
107 c.name,
108 c.ty.as_ref().map(Into::into),
109 c.refines.as_ref().map(Into::into),
110 )
111 }));
112 }
113 ComponentDefinedType::List(l) => {
114 encoder.list(l.element.as_ref());
115 }
116 ComponentDefinedType::Tuple(t) => {
117 encoder.tuple(t.fields.iter());
118 }
119 ComponentDefinedType::Flags(f) => {
120 encoder.flags(f.names.iter().copied());
121 }
122 ComponentDefinedType::Enum(e) => {
123 encoder.enum_type(e.names.iter().copied());
124 }
125 ComponentDefinedType::Option(o) => {
126 encoder.option(o.element.as_ref());
127 }
128 ComponentDefinedType::Result(e) => {
129 encoder.result(
130 e.ok.as_deref().map(Into::into),
131 e.err.as_deref().map(Into::into),
132 );
133 }
134 ComponentDefinedType::Own(i) => encoder.own((*i).into()),
135 ComponentDefinedType::Borrow(i) => encoder.borrow((*i).into()),
136 ComponentDefinedType::Stream(s) => encoder.stream(s.element.as_ref().into()),
137 ComponentDefinedType::Future(f) => encoder.future(f.element.as_deref().map(Into::into)),
138 }
139}
140
141#[derive(Default)]
142struct Encoder<'a> {
143 component: wasm_encoder::Component,
144 current_section_id: Option<u8>,
145
146 // Core sections
147 // Note: module sections are written immediately
148 core_instances: InstanceSection,
149 core_types: CoreTypeSection,
150
151 // Component sections
152 // Note: custom, component, start sections are written immediately
153 instances: ComponentInstanceSection,
154 aliases: ComponentAliasSection,
155 types: ComponentTypeSection,
156 funcs: CanonicalFunctionSection,
157 imports: ComponentImportSection,
158 exports: ComponentExportSection,
159
160 core_func_names: Vec<Option<&'a str>>,
161 core_table_names: Vec<Option<&'a str>>,
162 core_memory_names: Vec<Option<&'a str>>,
163 core_global_names: Vec<Option<&'a str>>,
164 core_type_names: Vec<Option<&'a str>>,
165 core_module_names: Vec<Option<&'a str>>,
166 core_instance_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 // Flush any in-progress section before encoding the customs section
177 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 // Flush any in-progress section before encoding the module
188 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 // TODO: replace this with a wasm-encoder based encoding (should return `wasm_encoder::Module`)
197 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 // Flush any in-progress section before encoding the component
248 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 // Flush any in-progress section before encoding the start section
309 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::Lower(info) => {
336 self.core_func_names.push(name);
337 self.funcs
338 .lower(info.func.idx.into(), info.opts.iter().map(Into::into));
339 }
340 CanonicalFuncKind::ResourceNew(info) => {
341 self.core_func_names.push(name);
342 self.funcs.resource_new(info.ty.into());
343 }
344 CanonicalFuncKind::ResourceDrop(info) => {
345 self.core_func_names.push(name);
346 self.funcs.resource_drop(info.ty.into());
347 }
348 CanonicalFuncKind::ResourceRep(info) => {
349 self.core_func_names.push(name);
350 self.funcs.resource_rep(info.ty.into());
351 }
352 CanonicalFuncKind::ThreadSpawn(info) => {
353 self.core_func_names.push(name);
354 self.funcs.thread_spawn(info.ty.into());
355 }
356 CanonicalFuncKind::ThreadHwConcurrency(_info) => {
357 self.core_func_names.push(name);
358 self.funcs.thread_hw_concurrency();
359 }
360 CanonicalFuncKind::TaskBackpressure => {
361 self.core_func_names.push(name);
362 self.funcs.task_backpressure();
363 }
364 CanonicalFuncKind::TaskReturn(info) => {
365 self.core_func_names.push(name);
366 self.funcs.task_return(info.ty.into());
367 }
368 CanonicalFuncKind::TaskWait(info) => {
369 self.core_func_names.push(name);
370 self.funcs.task_wait(info.async_, info.memory.idx.into());
371 }
372 CanonicalFuncKind::TaskPoll(info) => {
373 self.core_func_names.push(name);
374 self.funcs.task_poll(info.async_, info.memory.idx.into());
375 }
376 CanonicalFuncKind::TaskYield(info) => {
377 self.core_func_names.push(name);
378 self.funcs.task_yield(info.async_);
379 }
380 CanonicalFuncKind::SubtaskDrop => {
381 self.core_func_names.push(name);
382 self.funcs.subtask_drop();
383 }
384 CanonicalFuncKind::StreamNew(info) => {
385 self.core_func_names.push(name);
386 self.funcs.stream_new(info.ty.into());
387 }
388 CanonicalFuncKind::StreamRead(info) => {
389 self.core_func_names.push(name);
390 self.funcs
391 .stream_read(info.ty.into(), info.opts.iter().map(Into::into));
392 }
393 CanonicalFuncKind::StreamWrite(info) => {
394 self.core_func_names.push(name);
395 self.funcs
396 .stream_write(info.ty.into(), info.opts.iter().map(Into::into));
397 }
398 CanonicalFuncKind::StreamCancelRead(info) => {
399 self.core_func_names.push(name);
400 self.funcs.stream_cancel_read(info.ty.into(), info.async_);
401 }
402 CanonicalFuncKind::StreamCancelWrite(info) => {
403 self.core_func_names.push(name);
404 self.funcs.stream_cancel_write(info.ty.into(), info.async_);
405 }
406 CanonicalFuncKind::StreamCloseReadable(info) => {
407 self.core_func_names.push(name);
408 self.funcs.stream_close_readable(info.ty.into());
409 }
410 CanonicalFuncKind::StreamCloseWritable(info) => {
411 self.core_func_names.push(name);
412 self.funcs.stream_close_writable(info.ty.into());
413 }
414 CanonicalFuncKind::FutureNew(info) => {
415 self.core_func_names.push(name);
416 self.funcs.future_new(info.ty.into());
417 }
418 CanonicalFuncKind::FutureRead(info) => {
419 self.core_func_names.push(name);
420 self.funcs
421 .future_read(info.ty.into(), info.opts.iter().map(Into::into));
422 }
423 CanonicalFuncKind::FutureWrite(info) => {
424 self.core_func_names.push(name);
425 self.funcs
426 .future_write(info.ty.into(), info.opts.iter().map(Into::into));
427 }
428 CanonicalFuncKind::FutureCancelRead(info) => {
429 self.core_func_names.push(name);
430 self.funcs.future_cancel_read(info.ty.into(), info.async_);
431 }
432 CanonicalFuncKind::FutureCancelWrite(info) => {
433 self.core_func_names.push(name);
434 self.funcs.future_cancel_write(info.ty.into(), info.async_);
435 }
436 CanonicalFuncKind::FutureCloseReadable(info) => {
437 self.core_func_names.push(name);
438 self.funcs.future_close_readable(info.ty.into());
439 }
440 CanonicalFuncKind::FutureCloseWritable(info) => {
441 self.core_func_names.push(name);
442 self.funcs.future_close_writable(info.ty.into());
443 }
444 CanonicalFuncKind::ErrorContextNew(info) => {
445 self.core_func_names.push(name);
446 self.funcs
447 .error_context_new(info.opts.iter().map(Into::into));
448 }
449 CanonicalFuncKind::ErrorContextDebugMessage(info) => {
450 self.core_func_names.push(name);
451 self.funcs
452 .error_context_debug_message(info.opts.iter().map(Into::into));
453 }
454 CanonicalFuncKind::ErrorContextDrop => {
455 self.core_func_names.push(name);
456 self.funcs.error_context_drop();
457 }
458 }
459
460 self.flush(Some(self.funcs.id()));
461 }
462
463 fn encode_import(&mut self, import: &ComponentImport<'a>) {
464 let name = get_name(&import.item.id, &import.item.name);
465 self.names_for_item_kind(&import.item.kind).push(name);
466 self.imports
467 .import(import.name.0, (&import.item.kind).into());
468 self.flush(Some(self.imports.id()));
469 }
470
471 fn encode_export(&mut self, export: &ComponentExport<'a>) {
472 let name = get_name(&export.id, &export.debug_name);
473 let (kind, index) = (&export.kind).into();
474 self.exports.export(
475 export.name.0,
476 kind,
477 index,
478 export.ty.as_ref().map(|ty| (&ty.0.kind).into()),
479 );
480 match &export.kind {
481 ComponentExportKind::CoreModule(_) => self.core_module_names.push(name),
482 ComponentExportKind::Func(_) => self.func_names.push(name),
483 ComponentExportKind::Instance(_) => self.instance_names.push(name),
484 ComponentExportKind::Value(_) => self.value_names.push(name),
485 ComponentExportKind::Component(_) => self.component_names.push(name),
486 ComponentExportKind::Type(_) => self.type_names.push(name),
487 }
488 self.flush(Some(self.exports.id()));
489 }
490
491 fn flush(&mut self, section_id: Option<u8>) {
492 if self.current_section_id == section_id {
493 return;
494 }
495
496 if let Some(id) = self.current_section_id {
497 match id {
498 // 0 => custom sections are written immediately
499 // 1 => core modules sections are written immediately
500 2 => {
501 assert_eq!(id, self.core_instances.id());
502 self.component.section(&self.core_instances);
503 self.core_instances = Default::default();
504 }
505 3 => {
506 assert_eq!(id, self.core_types.id());
507 self.component.section(&self.core_types);
508 self.core_types = Default::default();
509 }
510 // 4 => components sections are written immediately
511 5 => {
512 assert_eq!(id, self.instances.id());
513 self.component.section(&self.instances);
514 self.instances = Default::default();
515 }
516 6 => {
517 assert_eq!(id, self.aliases.id());
518 self.component.section(&self.aliases);
519 self.aliases = Default::default();
520 }
521 7 => {
522 assert_eq!(id, self.types.id());
523 self.component.section(&self.types);
524 self.types = Default::default();
525 }
526 8 => {
527 assert_eq!(id, self.funcs.id());
528 self.component.section(&self.funcs);
529 self.funcs = Default::default();
530 }
531 // 9 => start sections are written immediately
532 10 => {
533 assert_eq!(id, self.imports.id());
534 self.component.section(&self.imports);
535 self.imports = Default::default();
536 }
537 11 => {
538 assert_eq!(id, self.exports.id());
539 self.component.section(&self.exports);
540 self.exports = Default::default();
541 }
542 _ => unreachable!("unknown incremental component section id: {}", id),
543 }
544 }
545
546 self.current_section_id = section_id
547 }
548
549 fn encode_names(
550 &mut self,
551 component_id: &Option<Id<'_>>,
552 component_name: &Option<NameAnnotation<'_>>,
553 ) {
554 let mut names = ComponentNameSection::new();
555 if let Some(name) = get_name(component_id, component_name) {
556 names.component(name);
557 }
558
559 let mut funcs = |list: &[Option<&str>], append: fn(&mut ComponentNameSection, &NameMap)| {
560 let mut map = NameMap::new();
561 for (i, entry) in list.iter().enumerate() {
562 if let Some(name) = entry {
563 map.append(i as u32, name);
564 }
565 }
566 if !map.is_empty() {
567 append(&mut names, &map);
568 }
569 };
570
571 funcs(&self.core_func_names, ComponentNameSection::core_funcs);
572 funcs(&self.core_table_names, ComponentNameSection::core_tables);
573 funcs(&self.core_memory_names, ComponentNameSection::core_memories);
574 funcs(&self.core_global_names, ComponentNameSection::core_globals);
575 funcs(&self.core_type_names, ComponentNameSection::core_types);
576 funcs(&self.core_module_names, ComponentNameSection::core_modules);
577 funcs(
578 &self.core_instance_names,
579 ComponentNameSection::core_instances,
580 );
581 funcs(&self.func_names, ComponentNameSection::funcs);
582 funcs(&self.value_names, ComponentNameSection::values);
583 funcs(&self.type_names, ComponentNameSection::types);
584 funcs(&self.component_names, ComponentNameSection::components);
585 funcs(&self.instance_names, ComponentNameSection::instances);
586
587 if !names.is_empty() {
588 self.component.section(&names);
589 }
590 }
591
592 fn names_for_component_export_alias(
593 &mut self,
594 kind: ComponentExportAliasKind,
595 ) -> &mut Vec<Option<&'a str>> {
596 match kind {
597 ComponentExportAliasKind::Func => &mut self.func_names,
598 ComponentExportAliasKind::CoreModule => &mut self.core_module_names,
599 ComponentExportAliasKind::Value => &mut self.value_names,
600 ComponentExportAliasKind::Type => &mut self.type_names,
601 ComponentExportAliasKind::Component => &mut self.component_names,
602 ComponentExportAliasKind::Instance => &mut self.instance_names,
603 }
604 }
605
606 fn names_for_component_outer_alias(
607 &mut self,
608 kind: ComponentOuterAliasKind,
609 ) -> &mut Vec<Option<&'a str>> {
610 match kind {
611 ComponentOuterAliasKind::CoreModule => &mut self.core_module_names,
612 ComponentOuterAliasKind::CoreType => &mut self.core_type_names,
613 ComponentOuterAliasKind::Component => &mut self.component_names,
614 ComponentOuterAliasKind::Type => &mut self.type_names,
615 }
616 }
617
618 fn names_for_core_export_alias(&mut self, kind: core::ExportKind) -> &mut Vec<Option<&'a str>> {
619 match kind {
620 core::ExportKind::Func => &mut self.core_func_names,
621 core::ExportKind::Global => &mut self.core_global_names,
622 core::ExportKind::Table => &mut self.core_table_names,
623 core::ExportKind::Memory => &mut self.core_memory_names,
624 core::ExportKind::Tag => unimplemented!(),
625 }
626 }
627
628 fn names_for_item_kind(&mut self, kind: &ItemSigKind) -> &mut Vec<Option<&'a str>> {
629 match kind {
630 ItemSigKind::CoreModule(_) => &mut self.core_module_names,
631 ItemSigKind::Func(_) => &mut self.func_names,
632 ItemSigKind::Component(_) => &mut self.component_names,
633 ItemSigKind::Instance(_) => &mut self.instance_names,
634 ItemSigKind::Value(_) => &mut self.value_names,
635 ItemSigKind::Type(_) => &mut self.type_names,
636 }
637 }
638}
639
640fn get_name<'a>(id: &Option<Id<'a>>, name: &Option<NameAnnotation<'a>>) -> Option<&'a str> {
641 name.as_ref().map(|n: &NameAnnotation<'_>| n.name).or_else(|| {
642 id.and_then(|id: Id<'a>| {
643 if id.is_gensym() {
644 None
645 } else {
646 Some(id.name())
647 }
648 })
649 })
650}
651
652impl Custom<'_> {
653 fn to_section(&self) -> wasm_encoder::CustomSection<'_> {
654 let mut ret: Vec = Vec::new();
655 for list: &&[u8] in self.data.iter() {
656 ret.extend_from_slice(list);
657 }
658 wasm_encoder::CustomSection {
659 name: self.name.into(),
660 data: ret.into(),
661 }
662 }
663}
664
665impl From<&CoreInstantiationArgKind<'_>> for wasm_encoder::ModuleArg {
666 fn from(kind: &CoreInstantiationArgKind) -> Self {
667 match kind {
668 CoreInstantiationArgKind::Instance(i: &CoreItemRef<'_, instance>) => {
669 wasm_encoder::ModuleArg::Instance(i.idx.into())
670 }
671 CoreInstantiationArgKind::BundleOfExports(..) => {
672 unreachable!("should be expanded already")
673 }
674 }
675 }
676}
677
678impl From<&CoreItemRef<'_, core::ExportKind>> for (wasm_encoder::ExportKind, u32) {
679 fn from(item: &CoreItemRef<'_, core::ExportKind>) -> Self {
680 match &item.kind {
681 core::ExportKind::Func => (wasm_encoder::ExportKind::Func, item.idx.into()),
682 core::ExportKind::Table => (wasm_encoder::ExportKind::Table, item.idx.into()),
683 core::ExportKind::Memory => (wasm_encoder::ExportKind::Memory, item.idx.into()),
684 core::ExportKind::Global => (wasm_encoder::ExportKind::Global, item.idx.into()),
685 core::ExportKind::Tag => (wasm_encoder::ExportKind::Tag, item.idx.into()),
686 }
687 }
688}
689
690impl<T> From<&ItemRef<'_, T>> for u32 {
691 fn from(i: &ItemRef<'_, T>) -> Self {
692 assert!(i.export_names.is_empty());
693 i.idx.into()
694 }
695}
696
697impl<T> From<&CoreTypeUse<'_, T>> for u32 {
698 fn from(u: &CoreTypeUse<'_, T>) -> Self {
699 match u {
700 CoreTypeUse::Inline(_) => unreachable!("should be expanded already"),
701 CoreTypeUse::Ref(r: &CoreItemRef<'_, r#type>) => r.idx.into(),
702 }
703 }
704}
705
706impl<T> From<&ComponentTypeUse<'_, T>> for u32 {
707 fn from(u: &ComponentTypeUse<'_, T>) -> Self {
708 match u {
709 ComponentTypeUse::Inline(_) => unreachable!("should be expanded already"),
710 ComponentTypeUse::Ref(r: &ItemRef<'_, r#type>) => r.idx.into(),
711 }
712 }
713}
714
715impl From<&ComponentValType<'_>> for wasm_encoder::ComponentValType {
716 fn from(r: &ComponentValType) -> Self {
717 match r {
718 ComponentValType::Inline(ComponentDefinedType::Primitive(p: &PrimitiveValType)) => {
719 Self::Primitive((*p).into())
720 }
721 ComponentValType::Ref(i: &Index<'_>) => Self::Type(u32::from(*i)),
722 ComponentValType::Inline(_) => unreachable!("should be expanded by now"),
723 }
724 }
725}
726
727impl From<PrimitiveValType> for wasm_encoder::PrimitiveValType {
728 fn from(p: PrimitiveValType) -> Self {
729 match p {
730 PrimitiveValType::Bool => Self::Bool,
731 PrimitiveValType::S8 => Self::S8,
732 PrimitiveValType::U8 => Self::U8,
733 PrimitiveValType::S16 => Self::S16,
734 PrimitiveValType::U16 => Self::U16,
735 PrimitiveValType::S32 => Self::S32,
736 PrimitiveValType::U32 => Self::U32,
737 PrimitiveValType::S64 => Self::S64,
738 PrimitiveValType::U64 => Self::U64,
739 PrimitiveValType::F32 => Self::F32,
740 PrimitiveValType::F64 => Self::F64,
741 PrimitiveValType::Char => Self::Char,
742 PrimitiveValType::String => Self::String,
743 }
744 }
745}
746
747impl From<&Refinement<'_>> for u32 {
748 fn from(r: &Refinement) -> Self {
749 match r {
750 Refinement::Index(..) => unreachable!("should be resolved by now"),
751 Refinement::Resolved(i: &u32) => *i,
752 }
753 }
754}
755
756impl From<&ItemSigKind<'_>> for wasm_encoder::ComponentTypeRef {
757 fn from(k: &ItemSigKind) -> Self {
758 match k {
759 ItemSigKind::Component(c: &ComponentTypeUse<'_, ComponentType<'_>>) => Self::Component(c.into()),
760 ItemSigKind::CoreModule(m: &CoreTypeUse<'_, ModuleType<'_>>) => Self::Module(m.into()),
761 ItemSigKind::Instance(i: &ComponentTypeUse<'_, InstanceType<'_>>) => Self::Instance(i.into()),
762 ItemSigKind::Value(v: &ComponentValTypeUse<'_>) => Self::Value((&v.0).into()),
763 ItemSigKind::Func(f: &ComponentTypeUse<'_, ComponentFunctionType<'_>>) => Self::Func(f.into()),
764 ItemSigKind::Type(TypeBounds::Eq(t: &Index<'_>)) => {
765 Self::Type(wasm_encoder::TypeBounds::Eq((*t).into()))
766 }
767 ItemSigKind::Type(TypeBounds::SubResource) => {
768 Self::Type(wasm_encoder::TypeBounds::SubResource)
769 }
770 }
771 }
772}
773
774impl From<&ComponentType<'_>> for wasm_encoder::ComponentType {
775 fn from(ty: &ComponentType) -> Self {
776 let mut encoded = wasm_encoder::ComponentType::new();
777
778 for decl in &ty.decls {
779 match decl {
780 ComponentTypeDecl::CoreType(t) => {
781 encode_core_type(encoded.core_type(), &t.def);
782 }
783 ComponentTypeDecl::Type(t) => {
784 encode_type(encoded.ty(), &t.def);
785 }
786 ComponentTypeDecl::Alias(a) => {
787 encoded.alias((&a.target).into());
788 }
789 ComponentTypeDecl::Import(i) => {
790 encoded.import(i.name.0, (&i.item.kind).into());
791 }
792 ComponentTypeDecl::Export(e) => {
793 encoded.export(e.name.0, (&e.item.kind).into());
794 }
795 }
796 }
797
798 encoded
799 }
800}
801
802impl From<&InstanceType<'_>> for wasm_encoder::InstanceType {
803 fn from(ty: &InstanceType) -> Self {
804 let mut encoded: InstanceType = wasm_encoder::InstanceType::new();
805
806 for decl: &InstanceTypeDecl<'_> in &ty.decls {
807 match decl {
808 InstanceTypeDecl::CoreType(t: &CoreType<'_>) => {
809 encode_core_type(encoder:encoded.core_type(), &t.def);
810 }
811 InstanceTypeDecl::Type(t: &Type<'_>) => {
812 encode_type(encoder:encoded.ty(), &t.def);
813 }
814 InstanceTypeDecl::Alias(a: &Alias<'_>) => {
815 encoded.alias((&a.target).into());
816 }
817 InstanceTypeDecl::Export(e: &ComponentExportType<'_>) => {
818 encoded.export(name:e.name.0, (&e.item.kind).into());
819 }
820 }
821 }
822
823 encoded
824 }
825}
826
827impl From<&ModuleType<'_>> for wasm_encoder::ModuleType {
828 fn from(ty: &ModuleType) -> Self {
829 let mut encoded = wasm_encoder::ModuleType::new();
830
831 for decl in &ty.decls {
832 match decl {
833 ModuleTypeDecl::Type(t) => {
834 encoded.ty().subtype(&t.to_subtype());
835 }
836 ModuleTypeDecl::Rec(rec) => {
837 encoded.ty().rec(rec.types.iter().map(|t| t.to_subtype()));
838 }
839 ModuleTypeDecl::Alias(a) => match &a.target {
840 AliasTarget::Outer {
841 outer,
842 index,
843 kind: ComponentOuterAliasKind::CoreType,
844 } => {
845 encoded.alias_outer_core_type(u32::from(*outer), u32::from(*index));
846 }
847 _ => unreachable!("only outer type aliases are supported"),
848 },
849 ModuleTypeDecl::Import(i) => {
850 encoded.import(i.module, i.field, i.item.to_entity_type());
851 }
852 ModuleTypeDecl::Export(name, item) => {
853 encoded.export(name, item.to_entity_type());
854 }
855 }
856 }
857
858 encoded
859 }
860}
861
862impl From<&InstantiationArgKind<'_>> for (wasm_encoder::ComponentExportKind, u32) {
863 fn from(kind: &InstantiationArgKind) -> Self {
864 match kind {
865 InstantiationArgKind::Item(i: &ComponentExportKind<'_>) => i.into(),
866 InstantiationArgKind::BundleOfExports(..) => unreachable!("should be expanded already"),
867 }
868 }
869}
870
871impl From<&ComponentExportKind<'_>> for (wasm_encoder::ComponentExportKind, u32) {
872 fn from(kind: &ComponentExportKind) -> Self {
873 match kind {
874 ComponentExportKind::CoreModule(m: &ItemRef<'_, module>) => {
875 (wasm_encoder::ComponentExportKind::Module, m.idx.into())
876 }
877 ComponentExportKind::Func(f: &ItemRef<'_, func>) => (wasm_encoder::ComponentExportKind::Func, f.idx.into()),
878 ComponentExportKind::Value(v: &ItemRef<'_, value>) => {
879 (wasm_encoder::ComponentExportKind::Value, v.idx.into())
880 }
881 ComponentExportKind::Type(t: &ItemRef<'_, r#type>) => (wasm_encoder::ComponentExportKind::Type, t.idx.into()),
882 ComponentExportKind::Component(c: &ItemRef<'_, component>) => {
883 (wasm_encoder::ComponentExportKind::Component, c.idx.into())
884 }
885 ComponentExportKind::Instance(i: &ItemRef<'_, instance>) => {
886 (wasm_encoder::ComponentExportKind::Instance, i.idx.into())
887 }
888 }
889 }
890}
891
892impl From<ComponentOuterAliasKind> for wasm_encoder::ComponentOuterAliasKind {
893 fn from(kind: ComponentOuterAliasKind) -> Self {
894 match kind {
895 ComponentOuterAliasKind::CoreModule => Self::CoreModule,
896 ComponentOuterAliasKind::CoreType => Self::CoreType,
897 ComponentOuterAliasKind::Type => Self::Type,
898 ComponentOuterAliasKind::Component => Self::Component,
899 }
900 }
901}
902
903impl From<ComponentExportAliasKind> for wasm_encoder::ComponentExportKind {
904 fn from(kind: ComponentExportAliasKind) -> Self {
905 match kind {
906 ComponentExportAliasKind::CoreModule => Self::Module,
907 ComponentExportAliasKind::Func => Self::Func,
908 ComponentExportAliasKind::Value => Self::Value,
909 ComponentExportAliasKind::Type => Self::Type,
910 ComponentExportAliasKind::Component => Self::Component,
911 ComponentExportAliasKind::Instance => Self::Instance,
912 }
913 }
914}
915
916impl From<&CanonOpt<'_>> for wasm_encoder::CanonicalOption {
917 fn from(opt: &CanonOpt) -> Self {
918 match opt {
919 CanonOpt::StringUtf8 => Self::UTF8,
920 CanonOpt::StringUtf16 => Self::UTF16,
921 CanonOpt::StringLatin1Utf16 => Self::CompactUTF16,
922 CanonOpt::Memory(m: &CoreItemRef<'_, memory>) => Self::Memory(m.idx.into()),
923 CanonOpt::Realloc(f: &CoreItemRef<'_, func>) => Self::Realloc(f.idx.into()),
924 CanonOpt::PostReturn(f: &CoreItemRef<'_, func>) => Self::PostReturn(f.idx.into()),
925 CanonOpt::Async => Self::Async,
926 CanonOpt::Callback(f: &CoreItemRef<'_, func>) => Self::Callback(f.idx.into()),
927 }
928 }
929}
930
931impl<'a> From<&AliasTarget<'a>> for wasm_encoder::Alias<'a> {
932 fn from(target: &AliasTarget<'a>) -> Self {
933 match target {
934 AliasTarget::Export {
935 instance,
936 name,
937 kind,
938 } => wasm_encoder::Alias::InstanceExport {
939 instance: (*instance).into(),
940 kind: (*kind).into(),
941 name,
942 },
943 AliasTarget::CoreExport {
944 instance,
945 name,
946 kind,
947 } => wasm_encoder::Alias::CoreInstanceExport {
948 instance: (*instance).into(),
949 kind: (*kind).into(),
950 name,
951 },
952 AliasTarget::Outer { outer, index, kind } => wasm_encoder::Alias::Outer {
953 count: (*outer).into(),
954 kind: (*kind).into(),
955 index: (*index).into(),
956 },
957 }
958 }
959}
960