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 }
444 }
445}
446
447impl TryFrom<wasmparser::ComponentFuncType<'_>> for ComponentFuncType {
448 type Error = String;
449
450 fn try_from(value: wasmparser::ComponentFuncType) -> Result<Self, Self::Error> {
451 Ok(ComponentFuncType {
452 params: value
453 .params
454 .iter()
455 .map(|&(name, typ)| typ.try_into().map(|t| (name.to_string(), t)))
456 .collect::<Result<Vec<_>, String>>()?,
457 result: value.result.map(|ty| ty.try_into()).transpose()?,
458 })
459 }
460}
461
462impl TryFrom<wasmparser::ComponentImportName<'_>> for ComponentExternName {
463 type Error = String;
464
465 fn try_from(value: wasmparser::ComponentImportName) -> Result<Self, Self::Error> {
466 Ok(ComponentExternName::Name(value.0.to_string()))
467 }
468}
469
470impl TryFrom<wasmparser::ComponentImport<'_>> for ComponentImport {
471 type Error = String;
472
473 fn try_from(value: wasmparser::ComponentImport) -> Result<Self, Self::Error> {
474 Ok(ComponentImport {
475 name: value.name.try_into()?,
476 desc: value.ty.try_into()?,
477 })
478 }
479}
480
481impl<'a> TryFrom<wasmparser::ComponentTypeDeclaration<'a>> for ComponentTypeDeclaration {
482 type Error = String;
483
484 fn try_from(value: wasmparser::ComponentTypeDeclaration<'a>) -> Result<Self, Self::Error> {
485 match value {
486 wasmparser::ComponentTypeDeclaration::CoreType(core_type) => {
487 Ok(ComponentTypeDeclaration::Core(core_type.try_into()?))
488 }
489 wasmparser::ComponentTypeDeclaration::Type(tpe) => {
490 Ok(ComponentTypeDeclaration::Type(tpe.try_into()?))
491 }
492 wasmparser::ComponentTypeDeclaration::Alias(alias) => {
493 Ok(ComponentTypeDeclaration::Alias(alias.try_into()?))
494 }
495 wasmparser::ComponentTypeDeclaration::Import(import) => {
496 Ok(ComponentTypeDeclaration::Import(import.try_into()?))
497 }
498 wasmparser::ComponentTypeDeclaration::Export { name, ty } => {
499 Ok(ComponentTypeDeclaration::Export {
500 name: name.try_into()?,
501 desc: ty.try_into()?,
502 })
503 }
504 }
505 }
506}
507
508impl<'a> TryFrom<wasmparser::InstanceTypeDeclaration<'a>> for InstanceTypeDeclaration {
509 type Error = String;
510
511 fn try_from(value: wasmparser::InstanceTypeDeclaration<'a>) -> Result<Self, Self::Error> {
512 match value {
513 wasmparser::InstanceTypeDeclaration::CoreType(core_type) => {
514 Ok(InstanceTypeDeclaration::Core(core_type.try_into()?))
515 }
516 wasmparser::InstanceTypeDeclaration::Type(tpe) => {
517 Ok(InstanceTypeDeclaration::Type(tpe.try_into()?))
518 }
519 wasmparser::InstanceTypeDeclaration::Alias(alias) => {
520 Ok(InstanceTypeDeclaration::Alias(alias.try_into()?))
521 }
522 wasmparser::InstanceTypeDeclaration::Export { name, ty } => {
523 Ok(InstanceTypeDeclaration::Export {
524 name: name.try_into()?,
525 desc: ty.try_into()?,
526 })
527 }
528 }
529 }
530}
531
532impl TryFrom<wasmparser::ComponentType<'_>> for ComponentType {
533 type Error = String;
534
535 fn try_from(value: wasmparser::ComponentType) -> Result<Self, Self::Error> {
536 match value {
537 wasmparser::ComponentType::Defined(component_defined_type) => {
538 Ok(ComponentType::Defined(component_defined_type.try_into()?))
539 }
540 wasmparser::ComponentType::Func(component_func_type) => {
541 Ok(ComponentType::Func(component_func_type.try_into()?))
542 }
543 wasmparser::ComponentType::Component(component_type_decls) => {
544 Ok(ComponentType::Component(ComponentTypeDeclarations(
545 component_type_decls
546 .iter()
547 .map(|component_type_decl| component_type_decl.clone().try_into())
548 .collect::<Result<Vec<_>, String>>()?,
549 )))
550 }
551 wasmparser::ComponentType::Instance(instancetype_decls) => {
552 Ok(ComponentType::Instance(InstanceTypeDeclarations(
553 instancetype_decls
554 .iter()
555 .map(|instancetype_decl| instancetype_decl.clone().try_into())
556 .collect::<Result<Vec<_>, String>>()?,
557 )))
558 }
559 wasmparser::ComponentType::Resource { rep, dtor } => Ok(ComponentType::Resource {
560 representation: rep.try_into()?,
561 destructor: dtor,
562 }),
563 }
564 }
565}
566
567impl TryFrom<wasmparser::CanonicalOption> for CanonicalOption {
568 type Error = String;
569
570 fn try_from(value: wasmparser::CanonicalOption) -> Result<Self, Self::Error> {
571 match value {
572 wasmparser::CanonicalOption::UTF8 => Ok(CanonicalOption::Utf8),
573 wasmparser::CanonicalOption::UTF16 => Ok(CanonicalOption::Utf16),
574 wasmparser::CanonicalOption::CompactUTF16 => Ok(CanonicalOption::CompactUtf16),
575 wasmparser::CanonicalOption::Memory(mem_idx) => Ok(CanonicalOption::Memory(mem_idx)),
576 wasmparser::CanonicalOption::Realloc(func_idx) => {
577 Ok(CanonicalOption::Realloc(func_idx))
578 }
579 wasmparser::CanonicalOption::PostReturn(func_idx) => {
580 Ok(CanonicalOption::PostReturn(func_idx))
581 }
582 wasmparser::CanonicalOption::Async => Ok(CanonicalOption::Async),
583 wasmparser::CanonicalOption::Callback(func_idx) => {
584 Ok(CanonicalOption::Callback(func_idx))
585 }
586 }
587 }
588}
589
590impl TryFrom<wasmparser::CanonicalFunction> for Canon {
591 type Error = String;
592
593 fn try_from(value: wasmparser::CanonicalFunction) -> Result<Self, Self::Error> {
594 match value {
595 wasmparser::CanonicalFunction::Lift {
596 core_func_index,
597 type_index,
598 options,
599 } => Ok(Canon::Lift {
600 func_idx: core_func_index,
601 function_type: type_index,
602 opts: options
603 .iter()
604 .map(|&opt| opt.try_into())
605 .collect::<Result<Vec<_>, String>>()?,
606 }),
607 wasmparser::CanonicalFunction::Lower {
608 func_index,
609 options,
610 } => Ok(Canon::Lower {
611 func_idx: func_index,
612 opts: options
613 .iter()
614 .map(|&opt| opt.try_into())
615 .collect::<Result<Vec<_>, String>>()?,
616 }),
617 wasmparser::CanonicalFunction::ResourceNew { resource } => {
618 Ok(Canon::ResourceNew { type_idx: resource })
619 }
620 wasmparser::CanonicalFunction::ResourceDrop { resource } => {
621 Ok(Canon::ResourceDrop { type_idx: resource })
622 }
623 wasmparser::CanonicalFunction::ResourceRep { resource } => {
624 Ok(Canon::ResourceRep { type_idx: resource })
625 }
626 CanonicalFunction::ThreadSpawn { .. } => {
627 Err("Threads proposal is not supported".to_string())
628 }
629 CanonicalFunction::ResourceDropAsync { .. } => {
630 Err("WASI P3 future and stream support is not supported yet".to_string())
631 }
632 CanonicalFunction::ThreadAvailableParallelism => {
633 Err("WASI P3 future and stream support is not supported yet".to_string())
634 }
635 CanonicalFunction::BackpressureSet => {
636 Err("WASI P3 future and stream support is not supported yet".to_string())
637 }
638 CanonicalFunction::TaskReturn { .. } => {
639 Err("WASI P3 future and stream support is not supported yet".to_string())
640 }
641 CanonicalFunction::Yield { .. } => {
642 Err("WASI P3 future and stream support is not supported yet".to_string())
643 }
644 CanonicalFunction::SubtaskDrop => {
645 Err("WASI P3 future and stream support is not supported yet".to_string())
646 }
647 CanonicalFunction::StreamNew { .. } => {
648 Err("WASI P3 future and stream support is not supported yet".to_string())
649 }
650 CanonicalFunction::StreamRead { .. } => {
651 Err("WASI P3 future and stream support is not supported yet".to_string())
652 }
653 CanonicalFunction::StreamWrite { .. } => {
654 Err("WASI P3 future and stream support is not supported yet".to_string())
655 }
656 CanonicalFunction::StreamCancelRead { .. } => {
657 Err("WASI P3 future and stream support is not supported yet".to_string())
658 }
659 CanonicalFunction::StreamCancelWrite { .. } => {
660 Err("WASI P3 future and stream support is not supported yet".to_string())
661 }
662 CanonicalFunction::StreamCloseReadable { .. } => {
663 Err("WASI P3 future and stream support is not supported yet".to_string())
664 }
665 CanonicalFunction::StreamCloseWritable { .. } => {
666 Err("WASI P3 future and stream support is not supported yet".to_string())
667 }
668 CanonicalFunction::FutureNew { .. } => {
669 Err("WASI P3 future and stream support is not supported yet".to_string())
670 }
671 CanonicalFunction::FutureRead { .. } => {
672 Err("WASI P3 future and stream support is not supported yet".to_string())
673 }
674 CanonicalFunction::FutureWrite { .. } => {
675 Err("WASI P3 future and stream support is not supported yet".to_string())
676 }
677 CanonicalFunction::FutureCancelRead { .. } => {
678 Err("WASI P3 future and stream support is not supported yet".to_string())
679 }
680 CanonicalFunction::FutureCancelWrite { .. } => {
681 Err("WASI P3 future and stream support is not supported yet".to_string())
682 }
683 CanonicalFunction::FutureCloseReadable { .. } => {
684 Err("WASI P3 future and stream support is not supported yet".to_string())
685 }
686 CanonicalFunction::FutureCloseWritable { .. } => {
687 Err("WASI P3 future and stream support is not supported yet".to_string())
688 }
689 CanonicalFunction::ErrorContextNew { .. } => {
690 Err("WASI P3 future and stream support is not supported yet".to_string())
691 }
692 CanonicalFunction::ErrorContextDebugMessage { .. } => {
693 Err("WASI P3 future and stream support is not supported yet".to_string())
694 }
695 CanonicalFunction::ErrorContextDrop => {
696 Err("WASI P3 future and stream support is not supported yet".to_string())
697 }
698 CanonicalFunction::WaitableSetNew => {
699 Err("WASI P3 future and stream support is not supported yet".to_string())
700 }
701 CanonicalFunction::WaitableSetWait { .. } => {
702 Err("WASI P3 future and stream support is not supported yet".to_string())
703 }
704 CanonicalFunction::WaitableSetPoll { .. } => {
705 Err("WASI P3 future and stream support is not supported yet".to_string())
706 }
707 CanonicalFunction::WaitableSetDrop => {
708 Err("WASI P3 future and stream support is not supported yet".to_string())
709 }
710 CanonicalFunction::WaitableJoin => {
711 Err("WASI P3 future and stream support is not supported yet".to_string())
712 }
713 }
714 }
715}
716
717impl TryFrom<wasmparser::ComponentStartFunction> for ComponentStart {
718 type Error = String;
719
720 fn try_from(value: wasmparser::ComponentStartFunction) -> Result<Self, Self::Error> {
721 Ok(ComponentStart {
722 func_idx: value.func_index,
723 args: value.arguments.to_vec(),
724 results: value.results,
725 })
726 }
727}
728
729#[allow(clippy::type_complexity)]
730fn parse_component_sections<Ast>(
731 mut parser: Parser,
732 mut remaining: &[u8],
733) -> Result<
734 (
735 Sections<ComponentIndexSpace, ComponentSectionType, ComponentSection<Ast>>,
736 &[u8],
737 ),
738 String,
739>
740where
741 Ast: AstCustomization,
742 Ast::Expr: TryFromExprSource,
743 Ast::Data: From<Data<Ast::Expr>>,
744 Ast::Custom: From<Custom>,
745{
746 let mut sections = Vec::new();
747 loop {
748 let payload = match parser
749 .parse(remaining, true)
750 .map_err(|e| format!("Error parsing core module: {:?}", e))?
751 {
752 Chunk::Parsed { payload, consumed } => {
753 remaining = &remaining[consumed..];
754 payload
755 }
756 Chunk::NeedMoreData { .. } => {
757 return Err("Unexpected end of component binary".to_string());
758 }
759 };
760 match payload {
761 Payload::Version { .. } => {}
762 Payload::TypeSection(_) => {
763 return Err("Unexpected core type section in component".to_string());
764 }
765
766 Payload::ImportSection(_) => {
767 return Err("Unexpected core import section in component".to_string());
768 }
769
770 Payload::FunctionSection(_) => {
771 return Err("Unexpected core function section in component".to_string());
772 }
773
774 Payload::TableSection(_) => {
775 return Err("Unexpected core table section in component".to_string());
776 }
777
778 Payload::MemorySection(_) => {
779 return Err("Unexpected core memory section in component".to_string());
780 }
781
782 Payload::TagSection(_) => {
783 return Err("Unexpected core tag section in component".to_string());
784 }
785 Payload::GlobalSection(_) => {
786 return Err("Unexpected core global section in component".to_string());
787 }
788
789 Payload::ExportSection(_) => {
790 return Err("Unexpected core export section in component".to_string());
791 }
792
793 Payload::StartSection { .. } => {
794 return Err("Unexpected core start section in component".to_string());
795 }
796
797 Payload::ElementSection(_) => {
798 return Err("Unexpected core element section in component".to_string());
799 }
800
801 Payload::DataCountSection { .. } => {
802 return Err("Unexpected core data count section in component".to_string());
803 }
804
805 Payload::DataSection(_) => {
806 return Err("Unexpected core data section in component".to_string());
807 }
808
809 Payload::CodeSectionStart { .. } => {
810 return Err("Unexpected core code section in component".to_string());
811 }
812
813 Payload::CodeSectionEntry(_) => {
814 return Err("Unexpected core code section in component".to_string());
815 }
816
817 Payload::CustomSection(reader) => sections.push(ComponentSection::Custom(
818 Custom {
819 name: reader.name().to_string(),
820 data: reader.data().to_vec(),
821 }
822 .into(),
823 )),
824 Payload::End(_) => {
825 break;
826 }
827 Payload::InstanceSection(reader) => {
828 for instance in reader {
829 let instance = instance.map_err(|e| {
830 format!("Error parsing component core instance section: {:?}", e)
831 })?;
832 sections.push(ComponentSection::CoreInstance(instance.try_into()?))
833 }
834 }
835 Payload::CoreTypeSection(reader) => {
836 for core_type in reader {
837 let core_type = core_type.map_err(|e| {
838 format!("Error parsing component core type section: {:?}", e)
839 })?;
840 sections.push(ComponentSection::CoreType(core_type.try_into()?))
841 }
842 }
843 Payload::ModuleSection {
844 parser,
845 unchecked_range,
846 } => {
847 let module: Module<Ast> =
848 (parser, &remaining[..unchecked_range.len()]).try_into()?;
849 remaining = &remaining[(unchecked_range.end - unchecked_range.start)..];
850 sections.push(ComponentSection::Module(module))
851 }
852 Payload::ComponentSection { parser, .. } => {
853 let (component, new_remaining) = parse_component(parser, remaining)?;
854 remaining = new_remaining;
855 sections.push(ComponentSection::Component(component))
856 }
857 Payload::ComponentInstanceSection(reader) => {
858 for component_instance in reader {
859 let component_instance = component_instance.map_err(|e| {
860 format!("Error parsing component instance section: {:?}", e)
861 })?;
862 sections.push(ComponentSection::Instance(component_instance.try_into()?))
863 }
864 }
865 Payload::ComponentAliasSection(reader) => {
866 for alias in reader {
867 let alias = alias
868 .map_err(|e| format!("Error parsing component alias section: {:?}", e))?;
869 sections.push(ComponentSection::Alias(alias.try_into()?))
870 }
871 }
872 Payload::ComponentTypeSection(reader) => {
873 for component_type in reader {
874 let component_type = component_type
875 .map_err(|e| format!("Error parsing component type section: {:?}", e))?;
876 sections.push(ComponentSection::Type(component_type.try_into()?))
877 }
878 }
879 Payload::ComponentCanonicalSection(reader) => {
880 for canon in reader {
881 let canon = canon.map_err(|e| {
882 format!("Error parsing component canonical section: {:?}", e)
883 })?;
884 sections.push(ComponentSection::Canon(canon.try_into()?))
885 }
886 }
887 Payload::ComponentStartSection { start, .. } => {
888 sections.push(ComponentSection::Start(start.try_into()?))
889 }
890 Payload::ComponentImportSection(reader) => {
891 for import in reader {
892 let import = import
893 .map_err(|e| format!("Error parsing component import section: {:?}", e))?;
894 sections.push(ComponentSection::Import(import.try_into()?))
895 }
896 }
897 Payload::ComponentExportSection(reader) => {
898 for export in reader {
899 let export = export
900 .map_err(|e| format!("Error parsing component export section: {:?}", e))?;
901 sections.push(ComponentSection::Export(export.try_into()?))
902 }
903 }
904 Payload::UnknownSection { .. } => {
905 return Err("Unexpected unknown section in component".to_string());
906 }
907 _ => {
908 return Err("Unexpected section in component".to_string());
909 }
910 }
911 }
912
913 Ok((Sections::from_flat(sections), remaining))
914}
915
916pub fn parse_component<Ast>(
917 parser: Parser,
918 remaining: &[u8],
919) -> Result<(Component<Ast>, &[u8]), String>
920where
921 Ast: AstCustomization,
922 Ast::Expr: TryFromExprSource,
923 Ast::Data: From<Data<Ast::Expr>>,
924 Ast::Custom: From<Custom>,
925{
926 let (sections, remaining) = parse_component_sections(parser, remaining)?;
927 Ok((sections.into(), remaining))
928}