1use crate::component::*;
16use crate::core::{Data, TryFromExprSource};
17use crate::Sections;
18use wasmparser::{CanonicalFunction, Chunk, Parser, Payload};
19
20impl TryFrom<wasmparser::InstantiationArg<'_>> for InstantiationArg {
21 type Error = String;
22
23 fn try_from(value: wasmparser::InstantiationArg) -> Result<Self, Self::Error> {
24 let arg_ref = match value.kind {
25 wasmparser::InstantiationArgKind::Instance => {
26 InstantiationArgRef::Instance(value.index)
27 }
28 };
29 Ok(InstantiationArg {
30 name: value.name.to_string(),
31 arg_ref,
32 })
33 }
34}
35
36impl TryFrom<wasmparser::Instance<'_>> for Instance {
37 type Error = String;
38
39 fn try_from(value: wasmparser::Instance) -> Result<Self, Self::Error> {
40 match value {
41 wasmparser::Instance::Instantiate { module_index, args } => Ok(Instance::Instantiate {
42 module_idx: module_index,
43 args: args
44 .iter()
45 .map(|arg| arg.clone().try_into())
46 .collect::<Result<Vec<_>, String>>()?,
47 }),
48 wasmparser::Instance::FromExports(exports) => Ok(Instance::FromExports {
49 exports: exports
50 .iter()
51 .map(|&export| export.try_into())
52 .collect::<Result<Vec<_>, String>>()?,
53 }),
54 }
55 }
56}
57
58impl TryFrom<wasmparser::OuterAliasKind> for OuterAliasKind {
59 type Error = String;
60
61 fn try_from(value: wasmparser::OuterAliasKind) -> Result<Self, Self::Error> {
62 match value {
63 wasmparser::OuterAliasKind::Type => Ok(OuterAliasKind::Type),
64 }
65 }
66}
67
68impl TryFrom<wasmparser::ModuleTypeDeclaration<'_>> for ModuleDeclaration {
69 type Error = String;
70
71 fn try_from(value: wasmparser::ModuleTypeDeclaration) -> Result<Self, Self::Error> {
72 match value {
73 wasmparser::ModuleTypeDeclaration::Type(recgroup) => {
74 let subtype = recgroup.into_types().next().ok_or("Empty rec group")?;
75 Ok(ModuleDeclaration::Type {
76 typ: subtype.try_into()?,
77 })
78 }
79 wasmparser::ModuleTypeDeclaration::Export { name, ty } => {
80 Ok(ModuleDeclaration::Export {
81 name: name.to_string(),
82 desc: ty.try_into()?,
83 })
84 }
85 wasmparser::ModuleTypeDeclaration::OuterAlias { kind, count, index } => {
86 Ok(ModuleDeclaration::OuterAlias {
87 kind: kind.try_into()?,
88 target: AliasTarget { count, index },
89 })
90 }
91 wasmparser::ModuleTypeDeclaration::Import(import) => Ok(ModuleDeclaration::Import {
92 import: import.try_into()?,
93 }),
94 }
95 }
96}
97
98impl TryFrom<wasmparser::SubType> for FuncType {
99 type Error = String;
100
101 fn try_from(value: wasmparser::SubType) -> Result<Self, Self::Error> {
102 if value.is_final {
103 match value.composite_type.inner {
104 wasmparser::CompositeInnerType::Func(func_type) => Ok(func_type.try_into()?),
105 wasmparser::CompositeInnerType::Array(_) => {
106 Err("GC proposal is not supported".to_string())
107 }
108 wasmparser::CompositeInnerType::Struct(_) => {
109 Err("GC proposal is not supported".to_string())
110 }
111 wasmparser::CompositeInnerType::Cont(_) => {
112 Err("Task switching proposal is not supported".to_string())
113 }
114 }
115 } else {
116 Err("GC proposal is not supported".to_string())
117 }
118 }
119}
120
121impl TryFrom<wasmparser::CoreType<'_>> for CoreType {
122 type Error = String;
123
124 fn try_from(value: wasmparser::CoreType) -> Result<Self, Self::Error> {
125 match value {
126 wasmparser::CoreType::Rec(recgroup) => {
127 let subtype = recgroup.into_types().next().ok_or("Empty rec group")?;
128 Ok(CoreType::Function(subtype.try_into()?))
129 }
130 wasmparser::CoreType::Module(module_type_decl) => Ok(CoreType::Module(
131 module_type_decl
132 .iter()
133 .map(|module_decl| module_decl.clone().try_into())
134 .collect::<Result<Vec<_>, String>>()?,
135 )),
136 }
137 }
138}
139
140impl TryFrom<wasmparser::ComponentExternalKind> for ComponentExternalKind {
141 type Error = String;
142
143 fn try_from(value: wasmparser::ComponentExternalKind) -> Result<Self, Self::Error> {
144 match value {
145 wasmparser::ComponentExternalKind::Module => Ok(ComponentExternalKind::Module),
146 wasmparser::ComponentExternalKind::Func => Ok(ComponentExternalKind::Func),
147 wasmparser::ComponentExternalKind::Value => Ok(ComponentExternalKind::Value),
148 wasmparser::ComponentExternalKind::Type => Ok(ComponentExternalKind::Type),
149 wasmparser::ComponentExternalKind::Instance => Ok(ComponentExternalKind::Instance),
150 wasmparser::ComponentExternalKind::Component => Ok(ComponentExternalKind::Component),
151 }
152 }
153}
154
155impl<'a> TryFrom<wasmparser::ComponentInstantiationArg<'a>> for ComponentInstantiationArg {
156 type Error = String;
157
158 fn try_from(value: wasmparser::ComponentInstantiationArg<'a>) -> Result<Self, Self::Error> {
159 Ok(ComponentInstantiationArg {
160 name: value.name.to_string(),
161 kind: value.kind.try_into()?,
162 idx: value.index,
163 })
164 }
165}
166
167impl TryFrom<wasmparser::ComponentExportName<'_>> for ComponentExternName {
168 type Error = String;
169
170 fn try_from(value: wasmparser::ComponentExportName) -> Result<Self, Self::Error> {
171 Ok(ComponentExternName::Name(value.0.to_string()))
172 }
173}
174
175impl TryFrom<wasmparser::PrimitiveValType> for PrimitiveValueType {
176 type Error = String;
177
178 fn try_from(value: wasmparser::PrimitiveValType) -> Result<Self, Self::Error> {
179 match value {
180 wasmparser::PrimitiveValType::Bool => Ok(PrimitiveValueType::Bool),
181 wasmparser::PrimitiveValType::S8 => Ok(PrimitiveValueType::S8),
182 wasmparser::PrimitiveValType::U8 => Ok(PrimitiveValueType::U8),
183 wasmparser::PrimitiveValType::S16 => Ok(PrimitiveValueType::S16),
184 wasmparser::PrimitiveValType::U16 => Ok(PrimitiveValueType::U16),
185 wasmparser::PrimitiveValType::S32 => Ok(PrimitiveValueType::S32),
186 wasmparser::PrimitiveValType::U32 => Ok(PrimitiveValueType::U32),
187 wasmparser::PrimitiveValType::S64 => Ok(PrimitiveValueType::S64),
188 wasmparser::PrimitiveValType::U64 => Ok(PrimitiveValueType::U64),
189 wasmparser::PrimitiveValType::F32 => Ok(PrimitiveValueType::F32),
190 wasmparser::PrimitiveValType::F64 => Ok(PrimitiveValueType::F64),
191 wasmparser::PrimitiveValType::Char => Ok(PrimitiveValueType::Chr),
192 wasmparser::PrimitiveValType::String => Ok(PrimitiveValueType::Str),
193 wasmparser::PrimitiveValType::ErrorContext => Ok(PrimitiveValueType::ErrorContext),
194 }
195 }
196}
197
198impl TryFrom<wasmparser::ComponentValType> for ComponentValType {
199 type Error = String;
200
201 fn try_from(value: wasmparser::ComponentValType) -> Result<Self, Self::Error> {
202 match value {
203 wasmparser::ComponentValType::Primitive(primitive_val_type) => {
204 Ok(ComponentValType::Primitive(primitive_val_type.try_into()?))
205 }
206 wasmparser::ComponentValType::Type(component_type_idx) => {
207 Ok(ComponentValType::Defined(component_type_idx))
208 }
209 }
210 }
211}
212
213impl TryFrom<wasmparser::TypeBounds> for TypeBounds {
214 type Error = String;
215
216 fn try_from(value: wasmparser::TypeBounds) -> Result<Self, Self::Error> {
217 match value {
218 wasmparser::TypeBounds::Eq(component_type_idx) => {
219 Ok(TypeBounds::Eq(component_type_idx))
220 }
221 wasmparser::TypeBounds::SubResource => Ok(TypeBounds::SubResource),
222 }
223 }
224}
225
226impl TryFrom<wasmparser::ComponentTypeRef> for ComponentTypeRef {
227 type Error = String;
228
229 fn try_from(value: wasmparser::ComponentTypeRef) -> Result<Self, Self::Error> {
230 match value {
231 wasmparser::ComponentTypeRef::Module(module_idx) => {
232 Ok(ComponentTypeRef::Module(module_idx))
233 }
234 wasmparser::ComponentTypeRef::Func(func_idx) => Ok(ComponentTypeRef::Func(func_idx)),
235 wasmparser::ComponentTypeRef::Value(component_val_type) => {
236 Ok(ComponentTypeRef::Val(component_val_type.try_into()?))
237 }
238 wasmparser::ComponentTypeRef::Type(type_bounds) => {
239 Ok(ComponentTypeRef::Type(type_bounds.try_into()?))
240 }
241 wasmparser::ComponentTypeRef::Instance(instance_idx) => {
242 Ok(ComponentTypeRef::Instance(instance_idx))
243 }
244 wasmparser::ComponentTypeRef::Component(component_idx) => {
245 Ok(ComponentTypeRef::Component(component_idx))
246 }
247 }
248 }
249}
250
251impl<'a> TryFrom<wasmparser::ComponentExport<'a>> for ComponentExport {
252 type Error = String;
253
254 fn try_from(value: wasmparser::ComponentExport<'a>) -> Result<Self, Self::Error> {
255 Ok(ComponentExport {
256 name: value.name.try_into()?,
257 kind: value.kind.try_into()?,
258 idx: value.index,
259 desc: match value.ty {
260 Some(ty) => Some(ty.try_into()?),
261 None => None,
262 },
263 })
264 }
265}
266
267impl TryFrom<wasmparser::ComponentInstance<'_>> for ComponentInstance {
268 type Error = String;
269
270 fn try_from(value: wasmparser::ComponentInstance) -> Result<Self, Self::Error> {
271 match value {
272 wasmparser::ComponentInstance::Instantiate {
273 component_index,
274 args,
275 } => Ok(ComponentInstance::Instantiate {
276 component_idx: component_index,
277 args: args
278 .iter()
279 .map(|arg| arg.clone().try_into())
280 .collect::<Result<Vec<_>, String>>()?,
281 }),
282 wasmparser::ComponentInstance::FromExports(exports) => {
283 Ok(ComponentInstance::FromExports {
284 exports: exports
285 .iter()
286 .map(|export| export.clone().try_into())
287 .collect::<Result<Vec<_>, String>>()?,
288 })
289 }
290 }
291 }
292}
293
294impl TryFrom<wasmparser::ExternalKind> for ExportKind {
295 type Error = String;
296
297 fn try_from(value: wasmparser::ExternalKind) -> Result<Self, Self::Error> {
298 match value {
299 wasmparser::ExternalKind::Func => Ok(ExportKind::Func),
300 wasmparser::ExternalKind::Table => Ok(ExportKind::Table),
301 wasmparser::ExternalKind::Memory => Ok(ExportKind::Mem),
302 wasmparser::ExternalKind::Global => Ok(ExportKind::Global),
303 wasmparser::ExternalKind::Tag => {
304 Err("Exception handling proposal is not supported".to_string())
305 }
306 }
307 }
308}
309
310impl TryFrom<wasmparser::ComponentOuterAliasKind> for OuterAliasKind {
311 type Error = String;
312
313 fn try_from(value: wasmparser::ComponentOuterAliasKind) -> Result<Self, Self::Error> {
314 match value {
315 wasmparser::ComponentOuterAliasKind::CoreModule => Ok(OuterAliasKind::CoreModule),
316 wasmparser::ComponentOuterAliasKind::CoreType => Ok(OuterAliasKind::CoreType),
317 wasmparser::ComponentOuterAliasKind::Type => Ok(OuterAliasKind::Type),
318 wasmparser::ComponentOuterAliasKind::Component => Ok(OuterAliasKind::Component),
319 }
320 }
321}
322
323impl<'a> TryFrom<wasmparser::ComponentAlias<'a>> for Alias {
324 type Error = String;
325
326 fn try_from(value: wasmparser::ComponentAlias<'a>) -> Result<Self, Self::Error> {
327 match value {
328 wasmparser::ComponentAlias::InstanceExport {
329 kind,
330 instance_index,
331 name,
332 } => Ok(Alias::InstanceExport {
333 kind: kind.try_into()?,
334 instance_idx: instance_index,
335 name: name.to_string(),
336 }),
337 wasmparser::ComponentAlias::CoreInstanceExport {
338 kind,
339 instance_index,
340 name,
341 } => Ok(Alias::CoreInstanceExport {
342 kind: kind.try_into()?,
343 instance_idx: instance_index,
344 name: name.to_string(),
345 }),
346 wasmparser::ComponentAlias::Outer { kind, count, index } => Ok(Alias::Outer {
347 kind: kind.try_into()?,
348 target: AliasTarget { count, index },
349 }),
350 }
351 }
352}
353
354impl TryFrom<wasmparser::VariantCase<'_>> for VariantCase {
355 type Error = String;
356
357 fn try_from(value: wasmparser::VariantCase) -> Result<Self, Self::Error> {
358 Ok(VariantCase {
359 name: value.name.to_string(),
360 typ: match value.ty {
361 Some(ty) => Some(ty.try_into()?),
362 None => None,
363 },
364 refines: value.refines,
365 })
366 }
367}
368
369impl TryFrom<wasmparser::ComponentDefinedType<'_>> for ComponentDefinedType {
370 type Error = String;
371
372 fn try_from(value: wasmparser::ComponentDefinedType) -> Result<Self, Self::Error> {
373 match value {
374 wasmparser::ComponentDefinedType::Primitive(primitive_val_type) => {
375 Ok(ComponentDefinedType::Primitive {
376 typ: primitive_val_type.try_into()?,
377 })
378 }
379 wasmparser::ComponentDefinedType::Record(fields) => Ok(ComponentDefinedType::Record {
380 fields: fields
381 .iter()
382 .map(|&(name, typ)| typ.try_into().map(|t| (name.to_string(), t)))
383 .collect::<Result<Vec<_>, String>>()?,
384 }),
385 wasmparser::ComponentDefinedType::Variant(cases) => Ok(ComponentDefinedType::Variant {
386 cases: cases
387 .iter()
388 .map(|case| case.clone().try_into())
389 .collect::<Result<Vec<_>, String>>()?,
390 }),
391 wasmparser::ComponentDefinedType::List(tpe) => Ok(ComponentDefinedType::List {
392 elem: tpe.try_into()?,
393 }),
394 wasmparser::ComponentDefinedType::Tuple(types) => Ok(ComponentDefinedType::Tuple {
395 elems: types
396 .iter()
397 .map(|tpe| (*tpe).try_into())
398 .collect::<Result<Vec<_>, String>>()?,
399 }),
400 wasmparser::ComponentDefinedType::Flags(names) => Ok(ComponentDefinedType::Flags {
401 names: names
402 .iter()
403 .map(|name| name.to_string())
404 .collect::<Vec<_>>(),
405 }),
406 wasmparser::ComponentDefinedType::Enum(names) => Ok(ComponentDefinedType::Enum {
407 names: names
408 .iter()
409 .map(|name| name.to_string())
410 .collect::<Vec<_>>(),
411 }),
412 wasmparser::ComponentDefinedType::Option(tpe) => Ok(ComponentDefinedType::Option {
413 typ: tpe.try_into()?,
414 }),
415 wasmparser::ComponentDefinedType::Result { ok, err } => {
416 Ok(ComponentDefinedType::Result {
417 ok: match ok {
418 Some(tpe) => Some(tpe.try_into()?),
419 None => None,
420 },
421 err: match err {
422 Some(tpe) => Some(tpe.try_into()?),
423 None => None,
424 },
425 })
426 }
427 wasmparser::ComponentDefinedType::Own(component_type_idx) => {
428 Ok(ComponentDefinedType::Owned {
429 type_idx: component_type_idx,
430 })
431 }
432 wasmparser::ComponentDefinedType::Borrow(component_type_idx) => {
433 Ok(ComponentDefinedType::Borrowed {
434 type_idx: component_type_idx,
435 })
436 }
437 wasmparser::ComponentDefinedType::Future(tpe) => Ok(ComponentDefinedType::Future {
438 inner: tpe.map(|tpe| tpe.try_into()).transpose()?,
439 }),
440 wasmparser::ComponentDefinedType::Stream(tpe) => Ok(ComponentDefinedType::Stream {
441 inner: tpe.map(|tpe| tpe.try_into()).transpose()?,
442 }),
443 wasmparser::ComponentDefinedType::FixedSizeList(_, _) => {
444 Err("Fixed-size lists are not supported".to_string())
445 }
446 }
447 }
448}
449
450impl TryFrom<wasmparser::ComponentFuncType<'_>> for ComponentFuncType {
451 type Error = String;
452
453 fn try_from(value: wasmparser::ComponentFuncType) -> Result<Self, Self::Error> {
454 Ok(ComponentFuncType {
455 params: value
456 .params
457 .iter()
458 .map(|&(name, typ)| typ.try_into().map(|t| (name.to_string(), t)))
459 .collect::<Result<Vec<_>, String>>()?,
460 result: value.result.map(|ty| ty.try_into()).transpose()?,
461 })
462 }
463}
464
465impl TryFrom<wasmparser::ComponentImportName<'_>> for ComponentExternName {
466 type Error = String;
467
468 fn try_from(value: wasmparser::ComponentImportName) -> Result<Self, Self::Error> {
469 Ok(ComponentExternName::Name(value.0.to_string()))
470 }
471}
472
473impl TryFrom<wasmparser::ComponentImport<'_>> for ComponentImport {
474 type Error = String;
475
476 fn try_from(value: wasmparser::ComponentImport) -> Result<Self, Self::Error> {
477 Ok(ComponentImport {
478 name: value.name.try_into()?,
479 desc: value.ty.try_into()?,
480 })
481 }
482}
483
484impl<'a> TryFrom<wasmparser::ComponentTypeDeclaration<'a>> for ComponentTypeDeclaration {
485 type Error = String;
486
487 fn try_from(value: wasmparser::ComponentTypeDeclaration<'a>) -> Result<Self, Self::Error> {
488 match value {
489 wasmparser::ComponentTypeDeclaration::CoreType(core_type) => {
490 Ok(ComponentTypeDeclaration::Core(core_type.try_into()?))
491 }
492 wasmparser::ComponentTypeDeclaration::Type(tpe) => {
493 Ok(ComponentTypeDeclaration::Type(tpe.try_into()?))
494 }
495 wasmparser::ComponentTypeDeclaration::Alias(alias) => {
496 Ok(ComponentTypeDeclaration::Alias(alias.try_into()?))
497 }
498 wasmparser::ComponentTypeDeclaration::Import(import) => {
499 Ok(ComponentTypeDeclaration::Import(import.try_into()?))
500 }
501 wasmparser::ComponentTypeDeclaration::Export { name, ty } => {
502 Ok(ComponentTypeDeclaration::Export {
503 name: name.try_into()?,
504 desc: ty.try_into()?,
505 })
506 }
507 }
508 }
509}
510
511impl<'a> TryFrom<wasmparser::InstanceTypeDeclaration<'a>> for InstanceTypeDeclaration {
512 type Error = String;
513
514 fn try_from(value: wasmparser::InstanceTypeDeclaration<'a>) -> Result<Self, Self::Error> {
515 match value {
516 wasmparser::InstanceTypeDeclaration::CoreType(core_type) => {
517 Ok(InstanceTypeDeclaration::Core(core_type.try_into()?))
518 }
519 wasmparser::InstanceTypeDeclaration::Type(tpe) => {
520 Ok(InstanceTypeDeclaration::Type(tpe.try_into()?))
521 }
522 wasmparser::InstanceTypeDeclaration::Alias(alias) => {
523 Ok(InstanceTypeDeclaration::Alias(alias.try_into()?))
524 }
525 wasmparser::InstanceTypeDeclaration::Export { name, ty } => {
526 Ok(InstanceTypeDeclaration::Export {
527 name: name.try_into()?,
528 desc: ty.try_into()?,
529 })
530 }
531 }
532 }
533}
534
535impl TryFrom<wasmparser::ComponentType<'_>> for ComponentType {
536 type Error = String;
537
538 fn try_from(value: wasmparser::ComponentType) -> Result<Self, Self::Error> {
539 match value {
540 wasmparser::ComponentType::Defined(component_defined_type) => {
541 Ok(ComponentType::Defined(component_defined_type.try_into()?))
542 }
543 wasmparser::ComponentType::Func(component_func_type) => {
544 Ok(ComponentType::Func(component_func_type.try_into()?))
545 }
546 wasmparser::ComponentType::Component(component_type_decls) => {
547 Ok(ComponentType::Component(ComponentTypeDeclarations(
548 component_type_decls
549 .iter()
550 .map(|component_type_decl| component_type_decl.clone().try_into())
551 .collect::<Result<Vec<_>, String>>()?,
552 )))
553 }
554 wasmparser::ComponentType::Instance(instancetype_decls) => {
555 Ok(ComponentType::Instance(InstanceTypeDeclarations(
556 instancetype_decls
557 .iter()
558 .map(|instancetype_decl| instancetype_decl.clone().try_into())
559 .collect::<Result<Vec<_>, String>>()?,
560 )))
561 }
562 wasmparser::ComponentType::Resource { rep, dtor } => Ok(ComponentType::Resource {
563 representation: rep.try_into()?,
564 destructor: dtor,
565 }),
566 }
567 }
568}
569
570impl TryFrom<wasmparser::CanonicalOption> for CanonicalOption {
571 type Error = String;
572
573 fn try_from(value: wasmparser::CanonicalOption) -> Result<Self, Self::Error> {
574 match value {
575 wasmparser::CanonicalOption::UTF8 => Ok(CanonicalOption::Utf8),
576 wasmparser::CanonicalOption::UTF16 => Ok(CanonicalOption::Utf16),
577 wasmparser::CanonicalOption::CompactUTF16 => Ok(CanonicalOption::CompactUtf16),
578 wasmparser::CanonicalOption::Memory(mem_idx) => Ok(CanonicalOption::Memory(mem_idx)),
579 wasmparser::CanonicalOption::Realloc(func_idx) => {
580 Ok(CanonicalOption::Realloc(func_idx))
581 }
582 wasmparser::CanonicalOption::PostReturn(func_idx) => {
583 Ok(CanonicalOption::PostReturn(func_idx))
584 }
585 wasmparser::CanonicalOption::Async => Ok(CanonicalOption::Async),
586 wasmparser::CanonicalOption::Callback(func_idx) => {
587 Ok(CanonicalOption::Callback(func_idx))
588 }
589 wasmparser::CanonicalOption::CoreType(_) => {
590 Err("GC proposal is not supported".to_string())
591 }
592 wasmparser::CanonicalOption::Gc => Err("GC proposal is not supported".to_string()),
593 }
594 }
595}
596
597impl TryFrom<wasmparser::CanonicalFunction> for Canon {
598 type Error = String;
599
600 fn try_from(value: wasmparser::CanonicalFunction) -> Result<Self, Self::Error> {
601 match value {
602 wasmparser::CanonicalFunction::Lift {
603 core_func_index,
604 type_index,
605 options,
606 } => Ok(Canon::Lift {
607 func_idx: core_func_index,
608 function_type: type_index,
609 opts: options
610 .iter()
611 .map(|&opt| opt.try_into())
612 .collect::<Result<Vec<_>, String>>()?,
613 }),
614 wasmparser::CanonicalFunction::Lower {
615 func_index,
616 options,
617 } => Ok(Canon::Lower {
618 func_idx: func_index,
619 opts: options
620 .iter()
621 .map(|&opt| opt.try_into())
622 .collect::<Result<Vec<_>, String>>()?,
623 }),
624 wasmparser::CanonicalFunction::ResourceNew { resource } => {
625 Ok(Canon::ResourceNew { type_idx: resource })
626 }
627 wasmparser::CanonicalFunction::ResourceDrop { resource } => {
628 Ok(Canon::ResourceDrop { type_idx: resource })
629 }
630 wasmparser::CanonicalFunction::ResourceRep { resource } => {
631 Ok(Canon::ResourceRep { type_idx: resource })
632 }
633 CanonicalFunction::ThreadSpawnRef { .. } => {
634 Err("Threads proposal is not supported".to_string())
635 }
636 CanonicalFunction::ResourceDropAsync { .. } => {
637 Err("WASI P3 future and stream support is not supported yet".to_string())
638 }
639 CanonicalFunction::ThreadAvailableParallelism => {
640 Err("WASI P3 future and stream support is not supported yet".to_string())
641 }
642 CanonicalFunction::BackpressureSet => {
643 Err("WASI P3 future and stream support is not supported yet".to_string())
644 }
645 CanonicalFunction::TaskReturn { .. } => {
646 Err("WASI P3 future and stream support is not supported yet".to_string())
647 }
648 CanonicalFunction::Yield { .. } => {
649 Err("WASI P3 future and stream support is not supported yet".to_string())
650 }
651 CanonicalFunction::SubtaskDrop => {
652 Err("WASI P3 future and stream support is not supported yet".to_string())
653 }
654 CanonicalFunction::StreamNew { .. } => {
655 Err("WASI P3 future and stream support is not supported yet".to_string())
656 }
657 CanonicalFunction::StreamRead { .. } => {
658 Err("WASI P3 future and stream support is not supported yet".to_string())
659 }
660 CanonicalFunction::StreamWrite { .. } => {
661 Err("WASI P3 future and stream support is not supported yet".to_string())
662 }
663 CanonicalFunction::StreamCancelRead { .. } => {
664 Err("WASI P3 future and stream support is not supported yet".to_string())
665 }
666 CanonicalFunction::StreamCancelWrite { .. } => {
667 Err("WASI P3 future and stream support is not supported yet".to_string())
668 }
669 CanonicalFunction::StreamDropReadable { .. } => {
670 Err("WASI P3 future and stream support is not supported yet".to_string())
671 }
672 CanonicalFunction::StreamDropWritable { .. } => {
673 Err("WASI P3 future and stream support is not supported yet".to_string())
674 }
675 CanonicalFunction::FutureNew { .. } => {
676 Err("WASI P3 future and stream support is not supported yet".to_string())
677 }
678 CanonicalFunction::FutureRead { .. } => {
679 Err("WASI P3 future and stream support is not supported yet".to_string())
680 }
681 CanonicalFunction::FutureWrite { .. } => {
682 Err("WASI P3 future and stream support is not supported yet".to_string())
683 }
684 CanonicalFunction::FutureCancelRead { .. } => {
685 Err("WASI P3 future and stream support is not supported yet".to_string())
686 }
687 CanonicalFunction::FutureCancelWrite { .. } => {
688 Err("WASI P3 future and stream support is not supported yet".to_string())
689 }
690 CanonicalFunction::FutureDropReadable { .. } => {
691 Err("WASI P3 future and stream support is not supported yet".to_string())
692 }
693 CanonicalFunction::FutureDropWritable { .. } => {
694 Err("WASI P3 future and stream support is not supported yet".to_string())
695 }
696 CanonicalFunction::ErrorContextNew { .. } => {
697 Err("WASI P3 future and stream support is not supported yet".to_string())
698 }
699 CanonicalFunction::ErrorContextDebugMessage { .. } => {
700 Err("WASI P3 future and stream support is not supported yet".to_string())
701 }
702 CanonicalFunction::ErrorContextDrop => {
703 Err("WASI P3 future and stream support is not supported yet".to_string())
704 }
705 CanonicalFunction::WaitableSetNew => {
706 Err("WASI P3 future and stream support is not supported yet".to_string())
707 }
708 CanonicalFunction::WaitableSetWait { .. } => {
709 Err("WASI P3 future and stream support is not supported yet".to_string())
710 }
711 CanonicalFunction::WaitableSetPoll { .. } => {
712 Err("WASI P3 future and stream support is not supported yet".to_string())
713 }
714 CanonicalFunction::WaitableSetDrop => {
715 Err("WASI P3 future and stream support is not supported yet".to_string())
716 }
717 CanonicalFunction::WaitableJoin => {
718 Err("WASI P3 future and stream support is not supported yet".to_string())
719 }
720 CanonicalFunction::ThreadSpawnIndirect { .. } => {
721 Err("Threads proposal is not supported".to_string())
722 }
723 CanonicalFunction::TaskCancel => {
724 Err("WASI P3 future and stream support is not supported yet".to_string())
725 }
726 CanonicalFunction::ContextGet(_) => {
727 Err("WASI P3 future and stream support is not supported yet".to_string())
728 }
729 CanonicalFunction::ContextSet(_) => {
730 Err("WASI P3 future and stream support is not supported yet".to_string())
731 }
732 CanonicalFunction::SubtaskCancel { .. } => {
733 Err("WASI P3 future and stream support is not supported yet".to_string())
734 }
735 }
736 }
737}
738
739impl TryFrom<wasmparser::ComponentStartFunction> for ComponentStart {
740 type Error = String;
741
742 fn try_from(value: wasmparser::ComponentStartFunction) -> Result<Self, Self::Error> {
743 Ok(ComponentStart {
744 func_idx: value.func_index,
745 args: value.arguments.to_vec(),
746 results: value.results,
747 })
748 }
749}
750
751#[allow(clippy::type_complexity)]
752fn parse_component_sections<Ast>(
753 mut parser: Parser,
754 mut remaining: &[u8],
755) -> Result<
756 (
757 Sections<ComponentIndexSpace, ComponentSectionType, ComponentSection<Ast>>,
758 &[u8],
759 ),
760 String,
761>
762where
763 Ast: AstCustomization,
764 Ast::Expr: TryFromExprSource,
765 Ast::Data: From<Data<Ast::Expr>>,
766 Ast::Custom: From<Custom>,
767{
768 let mut sections = Vec::new();
769 loop {
770 let payload = match parser
771 .parse(remaining, true)
772 .map_err(|e| format!("Error parsing core module: {e:?}"))?
773 {
774 Chunk::Parsed { payload, consumed } => {
775 remaining = &remaining[consumed..];
776 payload
777 }
778 Chunk::NeedMoreData { .. } => {
779 return Err("Unexpected end of component binary".to_string());
780 }
781 };
782 match payload {
783 Payload::Version { .. } => {}
784 Payload::TypeSection(_) => {
785 return Err("Unexpected core type section in component".to_string());
786 }
787
788 Payload::ImportSection(_) => {
789 return Err("Unexpected core import section in component".to_string());
790 }
791
792 Payload::FunctionSection(_) => {
793 return Err("Unexpected core function section in component".to_string());
794 }
795
796 Payload::TableSection(_) => {
797 return Err("Unexpected core table section in component".to_string());
798 }
799
800 Payload::MemorySection(_) => {
801 return Err("Unexpected core memory section in component".to_string());
802 }
803
804 Payload::TagSection(_) => {
805 return Err("Unexpected core tag section in component".to_string());
806 }
807 Payload::GlobalSection(_) => {
808 return Err("Unexpected core global section in component".to_string());
809 }
810
811 Payload::ExportSection(_) => {
812 return Err("Unexpected core export section in component".to_string());
813 }
814
815 Payload::StartSection { .. } => {
816 return Err("Unexpected core start section in component".to_string());
817 }
818
819 Payload::ElementSection(_) => {
820 return Err("Unexpected core element section in component".to_string());
821 }
822
823 Payload::DataCountSection { .. } => {
824 return Err("Unexpected core data count section in component".to_string());
825 }
826
827 Payload::DataSection(_) => {
828 return Err("Unexpected core data section in component".to_string());
829 }
830
831 Payload::CodeSectionStart { .. } => {
832 return Err("Unexpected core code section in component".to_string());
833 }
834
835 Payload::CodeSectionEntry(_) => {
836 return Err("Unexpected core code section in component".to_string());
837 }
838
839 Payload::CustomSection(reader) => sections.push(ComponentSection::Custom(
840 Custom {
841 name: reader.name().to_string(),
842 data: reader.data().to_vec(),
843 }
844 .into(),
845 )),
846 Payload::End(_) => {
847 break;
848 }
849 Payload::InstanceSection(reader) => {
850 for instance in reader {
851 let instance = instance.map_err(|e| {
852 format!("Error parsing component core instance section: {e:?}")
853 })?;
854 sections.push(ComponentSection::CoreInstance(instance.try_into()?))
855 }
856 }
857 Payload::CoreTypeSection(reader) => {
858 for core_type in reader {
859 let core_type = core_type
860 .map_err(|e| format!("Error parsing component core type section: {e:?}"))?;
861 sections.push(ComponentSection::CoreType(core_type.try_into()?))
862 }
863 }
864 Payload::ModuleSection {
865 parser,
866 unchecked_range,
867 } => {
868 let module: Module<Ast> =
869 (parser, &remaining[..unchecked_range.len()]).try_into()?;
870 remaining = &remaining[(unchecked_range.end - unchecked_range.start)..];
871 sections.push(ComponentSection::Module(module))
872 }
873 Payload::ComponentSection { parser, .. } => {
874 let (component, new_remaining) = parse_component(parser, remaining)?;
875 remaining = new_remaining;
876 sections.push(ComponentSection::Component(component))
877 }
878 Payload::ComponentInstanceSection(reader) => {
879 for component_instance in reader {
880 let component_instance = component_instance
881 .map_err(|e| format!("Error parsing component instance section: {e:?}"))?;
882 sections.push(ComponentSection::Instance(component_instance.try_into()?))
883 }
884 }
885 Payload::ComponentAliasSection(reader) => {
886 for alias in reader {
887 let alias = alias
888 .map_err(|e| format!("Error parsing component alias section: {e:?}"))?;
889 sections.push(ComponentSection::Alias(alias.try_into()?))
890 }
891 }
892 Payload::ComponentTypeSection(reader) => {
893 for component_type in reader {
894 let component_type = component_type
895 .map_err(|e| format!("Error parsing component type section: {e:?}"))?;
896 sections.push(ComponentSection::Type(component_type.try_into()?))
897 }
898 }
899 Payload::ComponentCanonicalSection(reader) => {
900 for canon in reader {
901 let canon = canon
902 .map_err(|e| format!("Error parsing component canonical section: {e:?}"))?;
903 sections.push(ComponentSection::Canon(canon.try_into()?))
904 }
905 }
906 Payload::ComponentStartSection { start, .. } => {
907 sections.push(ComponentSection::Start(start.try_into()?))
908 }
909 Payload::ComponentImportSection(reader) => {
910 for import in reader {
911 let import = import
912 .map_err(|e| format!("Error parsing component import section: {e:?}"))?;
913 sections.push(ComponentSection::Import(import.try_into()?))
914 }
915 }
916 Payload::ComponentExportSection(reader) => {
917 for export in reader {
918 let export = export
919 .map_err(|e| format!("Error parsing component export section: {e:?}"))?;
920 sections.push(ComponentSection::Export(export.try_into()?))
921 }
922 }
923 Payload::UnknownSection { .. } => {
924 return Err("Unexpected unknown section in component".to_string());
925 }
926 _ => {
927 return Err("Unexpected section in component".to_string());
928 }
929 }
930 }
931
932 Ok((Sections::from_flat(sections), remaining))
933}
934
935pub fn parse_component<Ast>(
936 parser: Parser,
937 remaining: &[u8],
938) -> Result<(Component<Ast>, &[u8]), String>
939where
940 Ast: AstCustomization,
941 Ast::Expr: TryFromExprSource,
942 Ast::Data: From<Data<Ast::Expr>>,
943 Ast::Custom: From<Custom>,
944{
945 let (sections, remaining) = parse_component_sections(parser, remaining)?;
946 Ok((sections.into(), remaining))
947}