1use crate::{
16 metadata, new_core_section_cache, AstCustomization, IndexSpace, Section, SectionCache,
17 SectionIndex, SectionType, Sections,
18};
19use mappable_rc::Mrc;
20use std::fmt::{Debug, Formatter};
21
22#[cfg(feature = "parser")]
23pub mod parser;
24#[cfg(feature = "writer")]
25pub mod writer;
26
27pub type DataIdx = u32;
28pub type ElemIdx = u32;
29pub type ExportIdx = u32;
30pub type FuncIdx = u32;
31pub type GlobalIdx = u32;
32pub type LabelIdx = u32;
33pub type LocalIdx = u32;
34pub type MemIdx = u32;
35pub type TableIdx = u32;
36pub type TypeIdx = u32;
37
38pub trait RetainsCustomSection {
41 fn name(&self) -> &str;
42 fn data(&self) -> &[u8];
43}
44
45#[derive(Debug, Clone, PartialEq)]
49pub enum CoreSection<Ast: AstCustomization> {
50 Type(FuncType),
51 Func(FuncTypeRef),
52 Code(FuncCode<Ast::Expr>),
53 Table(Table),
54 Mem(Mem),
55 Global(Global),
56 Elem(Elem<Ast::Expr>),
57 Data(Ast::Data),
58 DataCount(DataCount),
59 Start(Start),
60 Export(Export),
61 Import(Import),
62 Custom(Ast::Custom),
63}
64
65#[allow(unused)]
66impl<Ast: AstCustomization> CoreSection<Ast> {
67 pub fn as_type(&self) -> &FuncType {
68 match self {
69 CoreSection::Type(ty) => ty,
70 _ => panic!("Expected type section, got {}", self.type_name()),
71 }
72 }
73
74 pub fn as_func(&self) -> &FuncTypeRef {
75 match self {
76 CoreSection::Func(func) => func,
77 _ => panic!("Expected func section, got {}", self.type_name()),
78 }
79 }
80
81 pub fn as_code(&self) -> &FuncCode<Ast::Expr> {
82 match self {
83 CoreSection::Code(code) => code,
84 _ => panic!("Expected code section, got {}", self.type_name()),
85 }
86 }
87
88 pub fn as_table(&self) -> &Table {
89 match self {
90 CoreSection::Table(table) => table,
91 _ => panic!("Expected table section, got {}", self.type_name()),
92 }
93 }
94
95 pub fn as_mem(&self) -> &Mem {
96 match self {
97 CoreSection::Mem(mem) => mem,
98 _ => panic!("Expected mem section, got {}", self.type_name()),
99 }
100 }
101
102 pub fn as_global(&self) -> &Global {
103 match self {
104 CoreSection::Global(global) => global,
105 _ => panic!("Expected global section, got {}", self.type_name()),
106 }
107 }
108
109 pub fn as_elem(&self) -> &Elem<Ast::Expr> {
110 match self {
111 CoreSection::Elem(elem) => elem,
112 _ => panic!("Expected elem section, got {}", self.type_name()),
113 }
114 }
115
116 pub fn as_data(&self) -> &Ast::Data {
117 match self {
118 CoreSection::Data(data) => data,
119 _ => panic!("Expected data section, got {}", self.type_name()),
120 }
121 }
122
123 pub fn as_data_count(&self) -> &DataCount {
124 match self {
125 CoreSection::DataCount(data_count) => data_count,
126 _ => panic!("Expected data count section, got {}", self.type_name()),
127 }
128 }
129
130 pub fn as_start(&self) -> &Start {
131 match self {
132 CoreSection::Start(start) => start,
133 _ => panic!("Expected start section, got {}", self.type_name()),
134 }
135 }
136
137 pub fn as_export(&self) -> &Export {
138 match self {
139 CoreSection::Export(export) => export,
140 _ => panic!("Expected export section, got {}", self.type_name()),
141 }
142 }
143
144 pub fn as_import(&self) -> &Import {
145 match self {
146 CoreSection::Import(import) => import,
147 _ => panic!("Expected import section, got {}", self.type_name()),
148 }
149 }
150
151 pub fn as_custom(&self) -> &Ast::Custom {
152 match self {
153 CoreSection::Custom(custom) => custom,
154 _ => panic!("Expected custom section, got {}", self.type_name()),
155 }
156 }
157
158 pub fn type_name(&self) -> &'static str {
159 match self {
160 CoreSection::Type(_) => "type",
161 CoreSection::Func(_) => "func",
162 CoreSection::Code(_) => "code",
163 CoreSection::Table(_) => "table",
164 CoreSection::Mem(_) => "mem",
165 CoreSection::Global(_) => "global",
166 CoreSection::Elem(_) => "elem",
167 CoreSection::Data(_) => "data",
168 CoreSection::DataCount(_) => "data count",
169 CoreSection::Start(_) => "start",
170 CoreSection::Export(_) => "export",
171 CoreSection::Import(_) => "import",
172 CoreSection::Custom(_) => "custom",
173 }
174 }
175}
176
177impl<Ast: AstCustomization> Section<CoreIndexSpace, CoreSectionType> for CoreSection<Ast> {
178 fn index_space(&self) -> CoreIndexSpace {
179 match self {
180 CoreSection::Type(inner) => inner.index_space(),
181 CoreSection::Func(inner) => inner.index_space(),
182 CoreSection::Code(inner) => inner.index_space(),
183 CoreSection::Table(inner) => inner.index_space(),
184 CoreSection::Mem(inner) => inner.index_space(),
185 CoreSection::Global(inner) => inner.index_space(),
186 CoreSection::Elem(inner) => inner.index_space(),
187 CoreSection::Data(inner) => inner.index_space(),
188 CoreSection::DataCount(inner) => inner.index_space(),
189 CoreSection::Start(inner) => inner.index_space(),
190 CoreSection::Export(inner) => inner.index_space(),
191 CoreSection::Import(inner) => inner.index_space(),
192 CoreSection::Custom(inner) => inner.index_space(),
193 }
194 }
195
196 fn section_type(&self) -> CoreSectionType {
197 match self {
198 CoreSection::Type(inner) => inner.section_type(),
199 CoreSection::Func(inner) => inner.section_type(),
200 CoreSection::Code(inner) => inner.section_type(),
201 CoreSection::Table(inner) => inner.section_type(),
202 CoreSection::Mem(inner) => inner.section_type(),
203 CoreSection::Global(inner) => inner.section_type(),
204 CoreSection::Elem(inner) => inner.section_type(),
205 CoreSection::Data(inner) => inner.section_type(),
206 CoreSection::DataCount(inner) => inner.section_type(),
207 CoreSection::Start(inner) => inner.section_type(),
208 CoreSection::Export(inner) => inner.section_type(),
209 CoreSection::Import(inner) => inner.section_type(),
210 CoreSection::Custom(inner) => inner.section_type(),
211 }
212 }
213}
214
215#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
219pub enum CoreSectionType {
220 Type,
221 Func,
222 Code,
223 Table,
224 Mem,
225 Global,
226 Elem,
227 Data,
228 DataCount,
229 Start,
230 Export,
231 Import,
232 Custom,
233}
234
235impl SectionType for CoreSectionType {
236 fn allow_grouping(&self) -> bool {
237 match self {
238 CoreSectionType::Type => true,
239 CoreSectionType::Func => true,
240 CoreSectionType::Code => true,
241 CoreSectionType::Table => true,
242 CoreSectionType::Mem => true,
243 CoreSectionType::Global => true,
244 CoreSectionType::Elem => true,
245 CoreSectionType::Data => true,
246 CoreSectionType::DataCount => false,
247 CoreSectionType::Start => false,
248 CoreSectionType::Export => true,
249 CoreSectionType::Import => true,
250 CoreSectionType::Custom => false,
251 }
252 }
253}
254
255#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
259pub enum CoreIndexSpace {
260 Type,
261 Func,
262 Table,
263 Mem,
264 Global,
265 Elem,
266 Data,
267 Local,
268 Label,
269 Code,
270 Export,
271 Start,
272 Custom,
273}
274
275impl IndexSpace for CoreIndexSpace {
276 type Index = u32;
277}
278
279#[derive(Debug, Clone, PartialEq, Eq)]
291pub enum NumType {
292 I32,
293 I64,
294 F32,
295 F64,
296}
297
298#[derive(Debug, Clone, PartialEq, Eq)]
308pub enum VecType {
309 V128,
310}
311
312#[derive(Debug, Clone, PartialEq, Eq)]
323pub enum RefType {
324 FuncRef,
325 ExternRef,
326}
327
328#[derive(Debug, Clone, PartialEq, Eq)]
331pub enum ValType {
332 Num(NumType),
333 Vec(VecType),
334 Ref(RefType),
335}
336
337#[derive(Debug, Clone, PartialEq, Eq)]
338pub enum NumOrVecType {
339 Num(NumType),
340 Vec(VecType),
341}
342
343#[derive(Debug, Clone, PartialEq, Eq)]
346pub struct ResultType {
347 pub values: Vec<ValType>,
348}
349
350#[derive(Debug, Clone, PartialEq, Eq)]
353pub struct FuncType {
354 pub input: ResultType,
355 pub output: ResultType,
356}
357
358impl Section<CoreIndexSpace, CoreSectionType> for FuncType {
359 fn index_space(&self) -> CoreIndexSpace {
360 CoreIndexSpace::Type
361 }
362
363 fn section_type(&self) -> CoreSectionType {
364 CoreSectionType::Type
365 }
366}
367
368#[derive(Debug, Clone, PartialEq, Eq)]
373pub struct Limits {
374 pub min: u64,
375 pub max: Option<u64>,
376}
377
378#[derive(Debug, Clone, PartialEq, Eq)]
383pub struct MemType {
384 pub limits: Limits,
385}
386
387#[derive(Debug, Clone, PartialEq, Eq)]
392pub struct TableType {
393 pub limits: Limits,
394 pub elements: RefType,
395}
396
397#[derive(Debug, Clone, PartialEq, Eq)]
398pub enum Mut {
399 Const,
400 Var,
401}
402
403#[derive(Debug, Clone, PartialEq, Eq)]
405pub struct GlobalType {
406 pub mutability: Mut,
407 pub val_type: ValType,
408}
409
410#[derive(Debug, Clone, PartialEq, Eq)]
412pub enum ExternType {
413 Func(FuncType),
414 Table(TableType),
415 Mem(MemType),
416 Global(GlobalType),
417}
418
419#[derive(Debug, Clone, PartialEq, Eq)]
420pub struct FuncTypeRef {
421 pub type_idx: TypeIdx,
422}
423
424impl Section<CoreIndexSpace, CoreSectionType> for FuncTypeRef {
425 fn index_space(&self) -> CoreIndexSpace {
426 CoreIndexSpace::Func
427 }
428
429 fn section_type(&self) -> CoreSectionType {
430 CoreSectionType::Func
431 }
432}
433
434#[derive(Debug, Clone, PartialEq)]
435pub struct FuncCode<Expr> {
436 pub locals: Vec<ValType>,
437 pub body: Expr,
438}
439
440impl<Expr: Debug + Clone + PartialEq> Section<CoreIndexSpace, CoreSectionType> for FuncCode<Expr> {
441 fn index_space(&self) -> CoreIndexSpace {
442 CoreIndexSpace::Func
443 }
444
445 fn section_type(&self) -> CoreSectionType {
446 CoreSectionType::Code
447 }
448}
449
450#[derive(Debug, Clone, PartialEq)]
466pub struct Func<Expr: 'static> {
467 pub type_idx: TypeIdx,
468 code: Mrc<FuncCode<Expr>>,
469}
470
471impl<Expr: 'static> Func<Expr> {
472 pub fn locals(&self) -> Mrc<Vec<ValType>> {
473 Mrc::map(self.code.clone(), |code| &code.locals)
474 }
475
476 pub fn body(&self) -> Mrc<Expr> {
477 Mrc::map(self.code.clone(), |code| &code.body)
478 }
479}
480
481#[derive(Debug, Clone, PartialEq, Eq)]
492pub struct Table {
493 pub table_type: TableType,
494}
495
496impl Section<CoreIndexSpace, CoreSectionType> for Table {
497 fn index_space(&self) -> CoreIndexSpace {
498 CoreIndexSpace::Table
499 }
500
501 fn section_type(&self) -> CoreSectionType {
502 CoreSectionType::Table
503 }
504}
505
506#[derive(Debug, Clone, PartialEq, Eq)]
519pub struct Mem {
520 pub mem_type: MemType,
521}
522
523impl Section<CoreIndexSpace, CoreSectionType> for Mem {
524 fn index_space(&self) -> CoreIndexSpace {
525 CoreIndexSpace::Mem
526 }
527
528 fn section_type(&self) -> CoreSectionType {
529 CoreSectionType::Mem
530 }
531}
532
533#[derive(Debug, Clone, PartialEq)]
540pub struct Global {
541 pub global_type: GlobalType,
542 pub init: Expr,
543}
544
545impl Section<CoreIndexSpace, CoreSectionType> for Global {
546 fn index_space(&self) -> CoreIndexSpace {
547 CoreIndexSpace::Global
548 }
549
550 fn section_type(&self) -> CoreSectionType {
551 CoreSectionType::Global
552 }
553}
554
555#[derive(Debug, Clone, PartialEq)]
556pub enum ElemMode {
557 Passive,
558 Active { table_idx: TableIdx, offset: Expr },
559 Declarative,
560}
561
562#[derive(Debug, Clone, PartialEq)]
577pub struct Elem<Expr> {
578 pub ref_type: RefType,
579 pub init: Vec<Expr>,
580 pub mode: ElemMode,
581}
582
583impl<Expr: Debug + Clone + PartialEq> Section<CoreIndexSpace, CoreSectionType> for Elem<Expr> {
584 fn index_space(&self) -> CoreIndexSpace {
585 CoreIndexSpace::Elem
586 }
587
588 fn section_type(&self) -> CoreSectionType {
589 CoreSectionType::Elem
590 }
591}
592
593#[derive(Debug, Clone, PartialEq)]
594pub enum DataMode<Expr> {
595 Passive,
596 Active { memory: MemIdx, offset: Expr },
597}
598
599#[derive(Debug, Clone, PartialEq)]
612pub struct Data<Expr: Clone> {
613 init: Vec<u8>,
614 mode: DataMode<Expr>,
615}
616
617impl<Expr: Debug + Clone + PartialEq> Section<CoreIndexSpace, CoreSectionType> for Data<Expr> {
618 fn index_space(&self) -> CoreIndexSpace {
619 CoreIndexSpace::Data
620 }
621
622 fn section_type(&self) -> CoreSectionType {
623 CoreSectionType::Data
624 }
625}
626
627#[derive(Debug, Clone, PartialEq, Eq)]
628pub struct DataCount {
629 pub count: u32,
630}
631
632impl Section<CoreIndexSpace, CoreSectionType> for DataCount {
633 fn index_space(&self) -> CoreIndexSpace {
634 CoreIndexSpace::Data
635 }
636
637 fn section_type(&self) -> CoreSectionType {
638 CoreSectionType::DataCount
639 }
640}
641
642#[derive(Debug, Clone, PartialEq, Eq)]
645pub struct Start {
646 pub func: FuncIdx,
647}
648
649impl Section<CoreIndexSpace, CoreSectionType> for Start {
650 fn index_space(&self) -> CoreIndexSpace {
651 CoreIndexSpace::Start
652 }
653
654 fn section_type(&self) -> CoreSectionType {
655 CoreSectionType::Start
656 }
657}
658
659#[derive(Debug, Clone, PartialEq, Eq)]
660pub enum ExportDesc {
661 Func(FuncIdx),
662 Table(TableIdx),
663 Mem(MemIdx),
664 Global(GlobalIdx),
665}
666
667#[derive(Debug, Clone, PartialEq, Eq)]
674pub struct Export {
675 pub name: String,
676 pub desc: ExportDesc,
677}
678
679impl Section<CoreIndexSpace, CoreSectionType> for Export {
680 fn index_space(&self) -> CoreIndexSpace {
681 CoreIndexSpace::Export
682 }
683
684 fn section_type(&self) -> CoreSectionType {
685 CoreSectionType::Export
686 }
687}
688
689#[derive(Debug, Clone, PartialEq, Eq)]
690pub enum TypeRef {
691 Func(TypeIdx),
692 Table(TableType),
693 Mem(MemType),
694 Global(GlobalType),
695}
696
697#[derive(Debug, Clone, PartialEq, Eq)]
707pub struct Import {
708 pub module: String,
709 pub name: String,
710 pub desc: TypeRef,
711}
712
713impl Section<CoreIndexSpace, CoreSectionType> for Import {
714 fn index_space(&self) -> CoreIndexSpace {
715 CoreIndexSpace::Func
716 }
717
718 fn section_type(&self) -> CoreSectionType {
719 CoreSectionType::Import
720 }
721}
722
723#[derive(Debug, Clone, PartialEq, Eq)]
724pub struct Custom {
725 pub name: String,
726 pub data: Vec<u8>,
727}
728
729impl RetainsCustomSection for Custom {
730 fn name(&self) -> &str {
731 &self.name
732 }
733
734 fn data(&self) -> &[u8] {
735 &self.data
736 }
737}
738
739impl Section<CoreIndexSpace, CoreSectionType> for Custom {
740 fn index_space(&self) -> CoreIndexSpace {
741 CoreIndexSpace::Custom
742 }
743
744 fn section_type(&self) -> CoreSectionType {
745 CoreSectionType::Custom
746 }
747}
748
749#[derive(Debug, Clone, PartialEq)]
750pub struct Expr {
751 pub instrs: Vec<Instr>,
752}
753
754pub trait ExprSource: IntoIterator<Item = Result<Instr, String>> {
755 fn unparsed(self) -> Result<Vec<u8>, String>;
756}
757
758pub trait RetainsInstructions {
759 fn instructions(&self) -> &[Instr];
760}
761
762pub trait TryFromExprSource {
763 fn try_from<S: ExprSource>(value: S) -> Result<Self, String>
764 where
765 Self: Sized;
766}
767
768impl TryFromExprSource for Expr {
769 fn try_from<S: ExprSource>(value: S) -> Result<Self, String> {
770 let instrs = value.into_iter().collect::<Result<Vec<Instr>, String>>()?;
771 Ok(Self { instrs })
772 }
773}
774
775impl RetainsInstructions for Expr {
776 fn instructions(&self) -> &[Instr] {
777 &self.instrs
778 }
779}
780
781#[derive(Debug, Clone, PartialEq, Eq)]
782pub enum IntWidth {
783 I32,
784 I64,
785}
786
787#[derive(Debug, Clone, PartialEq, Eq)]
788pub enum FloatWidth {
789 F32,
790 F64,
791}
792
793#[derive(Debug, Clone, PartialEq, Eq)]
794pub enum Signedness {
795 Signed,
796 Unsigned,
797}
798
799#[derive(Debug, Clone, PartialEq, Eq)]
800pub enum IShape {
801 I8x16,
802 I16x8,
803 I32x4,
804 I64x2,
805}
806
807#[derive(Debug, Clone, PartialEq, Eq)]
808pub enum FShape {
809 F32x4,
810 F64x2,
811}
812
813#[derive(Debug, Clone, PartialEq, Eq)]
814pub enum Shape {
815 Int(IShape),
816 Float(FShape),
817}
818
819#[derive(Debug, Clone, PartialEq, Eq)]
820pub enum Half {
821 Low,
822 High,
823}
824
825#[derive(Debug, Clone, PartialEq, Eq)]
826pub struct MemArg {
827 pub align: u8,
828 pub offset: u32,
829}
830
831#[derive(Debug, Clone, PartialEq, Eq)]
832pub enum VectorLoadShape {
833 WW8,
834 WW16,
835 WW32,
836 WW64,
837}
838
839#[derive(Debug, Clone, PartialEq, Eq)]
840pub enum BlockType {
841 None,
842 Index(TypeIdx),
843 Value(ValType),
844}
845
846pub type LaneIdx = u8;
847
848#[derive(Debug, Clone, PartialEq)]
849pub enum Instr {
850 I32Const(i32),
852 I64Const(i64),
853 F32Const(f32),
854 F64Const(f64),
855
856 IEqz(IntWidth),
858
859 IEq(IntWidth),
861 INe(IntWidth),
862 ILt(IntWidth, Signedness),
863 IGt(IntWidth, Signedness),
864 ILe(IntWidth, Signedness),
865 IGe(IntWidth, Signedness),
866
867 FEq(FloatWidth),
869 FNe(FloatWidth),
870 FLt(FloatWidth),
871 FGt(FloatWidth),
872 FLe(FloatWidth),
873 FGe(FloatWidth),
874
875 IClz(IntWidth),
877 ICtz(IntWidth),
878 IPopCnt(IntWidth),
879
880 IAdd(IntWidth),
882 ISub(IntWidth),
883 IMul(IntWidth),
884 IDiv(IntWidth, Signedness),
885 IRem(IntWidth, Signedness),
886 IAnd(IntWidth),
887 IOr(IntWidth),
888 IXor(IntWidth),
889 IShl(IntWidth),
890 IShr(IntWidth, Signedness),
891 IRotL(IntWidth),
892 IRotR(IntWidth),
893
894 FAbs(FloatWidth),
896 FNeg(FloatWidth),
897 FCeil(FloatWidth),
898 FFloor(FloatWidth),
899 FTrunc(FloatWidth),
900 FNearest(FloatWidth),
901
902 FSqrt(FloatWidth),
904 FAdd(FloatWidth),
905 FSub(FloatWidth),
906 FMul(FloatWidth),
907 FDiv(FloatWidth),
908 FMin(FloatWidth),
909 FMax(FloatWidth),
910 FCopySign(FloatWidth),
911
912 I32WrapI64,
913
914 ITruncF(IntWidth, FloatWidth, Signedness),
915
916 I64ExtendI32(Signedness),
917 I64Extend32S,
918 IExtend8S(IntWidth),
919 IExtend16S(IntWidth),
920
921 FConvertI(FloatWidth, IntWidth, Signedness),
922
923 F32DemoteF64,
924 F64PromoteF32,
925
926 IReinterpretF(IntWidth),
927 FReinterpretI(FloatWidth),
928
929 ITruncSatF(IntWidth, FloatWidth, Signedness),
930
931 V128Const(i128),
933
934 V128Not,
936
937 V128And,
939 V128AndNot,
940 V128Or,
941 V128XOr,
942
943 V128BitSelect,
945
946 V128AnyTrue,
948
949 VI8x16Shuffle([LaneIdx; 16]),
950
951 VI18x16Swizzle,
952 VSplat(Shape),
953 VI8x16ExtractLane(Signedness, LaneIdx),
954 VI16x8ExtractLane(Signedness, LaneIdx),
955 VI32x4ExtractLane(LaneIdx),
956 VI64x2ExtractLane(LaneIdx),
957 VFExtractLane(FShape, LaneIdx),
958 VReplaceLane(Shape, LaneIdx),
959
960 VIEq(IShape),
962 VINe(IShape),
963 VILt(IShape, Signedness),
964 VIGt(IShape, Signedness),
965 VILe(IShape, Signedness),
966 VIGe(IShape, Signedness),
967 VI64x2Lt,
968 VI64x2Gt,
969 VI64x2Le,
970 VI64x2Ge,
971
972 VFEq(FShape),
974 VFNe(FShape),
975 VFLt(FShape),
976 VFGt(FShape),
977 VFLe(FShape),
978 VFGe(FShape),
979
980 VIAbs(IShape),
982 VINeg(IShape),
983
984 VI8x16PopCnt,
985 VI16x8Q15MulrSat,
986 VI32x4DotI16x8,
987
988 VFAbs(FShape),
990 VFNeg(FShape),
991 VFSqrt(FShape),
992 VFCeil(FShape),
993 VFFloor(FShape),
994 VFTrunc(FShape),
995 VFNearest(FShape),
996
997 VIAllTrue(IShape),
999
1000 VIBitMask(IShape),
1001
1002 VI8x16NarrowI16x8(Signedness),
1003 VI16x8NarrowI32x4(Signedness),
1004
1005 VI16x8ExtendI8x16(Half, Signedness),
1006 VI32x4ExtendI16x8(Half, Signedness),
1007 VI64x2ExtendI32x4(Half, Signedness),
1008
1009 VIShl(IShape),
1011 VIShr(IShape, Signedness),
1012
1013 VIAdd(IShape),
1015 VISub(IShape),
1016
1017 VIMin(IShape, Signedness),
1019 VIMax(IShape, Signedness),
1020
1021 VIAddSat(IShape, Signedness),
1023 VISubSat(IShape, Signedness),
1024
1025 VIMul(IShape),
1026 VIAvgr(IShape),
1027 VIExtMul(IShape, Half, Signedness),
1028 VIExtAddPairwise(IShape, Signedness),
1029
1030 VFAdd(FShape),
1032 VFSub(FShape),
1033 VFMul(FShape),
1034 VFDiv(FShape),
1035 VFMin(FShape),
1036 VFMax(FShape),
1037 VFPMin(FShape),
1038 VFPMax(FShape),
1039
1040 VI32x4TruncSatF32x4(Signedness),
1041 VI32x4TruncSatF64x2Zero(Signedness),
1042 VI32x4ConvertI32x4(Signedness),
1043 VF32x4DemoteF64x2Zero,
1044 VF64x2ConvertLowI32x4(Signedness),
1045 VF64x2PromoteLowI32x4,
1046
1047 RefNull(RefType),
1049 RefIsNull,
1050 RefFunc(FuncIdx),
1051
1052 Drop,
1054 Select(Option<Vec<ValType>>),
1055
1056 LocalGet(LocalIdx),
1058 LocalSet(LocalIdx),
1059 LocalTee(LocalIdx),
1060 GlobalGet(GlobalIdx),
1061 GlobalSet(GlobalIdx),
1062
1063 TableGet(TableIdx),
1065 TableSet(TableIdx),
1066 TableSize(TableIdx),
1067 TableGrow(TableIdx),
1068 TableFill(TableIdx),
1069 TableCopy {
1070 source: TableIdx,
1071 destination: TableIdx,
1072 },
1073 TableInit(TableIdx, ElemIdx),
1074 ElemDrop(ElemIdx),
1075
1076 Load(NumOrVecType, MemArg),
1078 Store(NumOrVecType, MemArg),
1079 Load8(NumType, Signedness, MemArg),
1080 Load16(NumType, Signedness, MemArg),
1081 Load32(Signedness, MemArg),
1082 Store8(NumType, MemArg),
1083 Store16(NumType, MemArg),
1084 Store32(MemArg),
1085 V128Load8x8(Signedness, MemArg),
1086 V128Load16x4(Signedness, MemArg),
1087 V128Load32x2(Signedness, MemArg),
1088 V128Load32Zero(MemArg),
1089 V128Load64Zero(MemArg),
1090 V128LoadSplat(VectorLoadShape, MemArg),
1091 V128LoadLane(VectorLoadShape, MemArg, LaneIdx),
1092 V128StoreLane(VectorLoadShape, MemArg, LaneIdx),
1093 MemorySize,
1094 MemoryGrow,
1095 MemoryFill,
1096 MemoryCopy,
1097 MemoryInit(DataIdx),
1098 DataDrop(DataIdx),
1099
1100 Nop,
1102 Unreachable,
1103 Block(BlockType, Vec<Instr>),
1104 Loop(BlockType, Vec<Instr>),
1105 If(BlockType, Vec<Instr>, Vec<Instr>),
1106 Br(LabelIdx),
1107 BrIf(LabelIdx),
1108 BrTable(Vec<LabelIdx>, LabelIdx),
1109 Return,
1110 Call(FuncIdx),
1111 CallIndirect(TableIdx, TypeIdx),
1112}
1113
1114#[derive(Debug, Clone)]
1115pub enum ImportOrFunc<Expr: 'static> {
1116 Import(Mrc<Import>),
1117 Func(Func<Expr>),
1118}
1119
1120type CoreSectionCache<T, Ast> = SectionCache<T, CoreIndexSpace, CoreSectionType, CoreSection<Ast>>;
1121type CoreSectionIndex<Ast> = SectionIndex<CoreIndexSpace, CoreSectionType, CoreSection<Ast>>;
1122
1123pub struct Module<Ast: AstCustomization + 'static> {
1127 sections: Sections<CoreIndexSpace, CoreSectionType, CoreSection<Ast>>,
1128
1129 types: CoreSectionCache<FuncType, Ast>,
1130 func_type_refs: CoreSectionCache<FuncTypeRef, Ast>,
1131 codes: CoreSectionCache<FuncCode<Ast::Expr>, Ast>,
1132 tables: CoreSectionCache<Table, Ast>,
1133 mems: CoreSectionCache<Mem, Ast>,
1134 globals: CoreSectionCache<Global, Ast>,
1135 elems: CoreSectionCache<Elem<Ast::Expr>, Ast>,
1136 datas: CoreSectionCache<Ast::Data, Ast>,
1137 start: CoreSectionCache<Start, Ast>,
1138 imports: CoreSectionCache<Import, Ast>,
1139 exports: CoreSectionCache<Export, Ast>,
1140 customs: CoreSectionCache<Ast::Custom, Ast>,
1141
1142 type_index: CoreSectionIndex<Ast>,
1143 func_index: CoreSectionIndex<Ast>,
1144 code_index: CoreSectionIndex<Ast>,
1145 table_index: CoreSectionIndex<Ast>,
1146 mem_index: CoreSectionIndex<Ast>,
1147 global_index: CoreSectionIndex<Ast>,
1148 elem_index: CoreSectionIndex<Ast>,
1149 data_index: CoreSectionIndex<Ast>,
1150 export_index: CoreSectionIndex<Ast>,
1151}
1152
1153#[cfg(feature = "parser")]
1154impl<Ast> Module<Ast>
1155where
1156 Ast: AstCustomization + 'static,
1157 Ast::Expr: TryFromExprSource,
1158 Ast::Data: From<Data<Ast::Expr>>,
1159 Ast::Custom: From<Custom>,
1160{
1161 pub fn from_bytes(bytes: &[u8]) -> Result<Self, String> {
1163 let parser = wasmparser::Parser::new(0);
1164 Self::try_from((parser, bytes))
1165 }
1166}
1167
1168#[cfg(feature = "writer")]
1169impl<Ast> Module<Ast>
1170where
1171 Ast: AstCustomization + 'static,
1172 Ast::Expr: RetainsInstructions,
1173 Ast::Data: Into<Data<Ast::Expr>>,
1174 Ast::Custom: Into<Custom>,
1175{
1176 pub fn into_bytes(self) -> Result<Vec<u8>, String> {
1178 let encoder: wasm_encoder::Module = self.try_into()?;
1179 Ok(encoder.finish())
1180 }
1181}
1182
1183impl<Ast: AstCustomization> Module<Ast> {
1184 pub fn empty() -> Self {
1186 Self::new(Sections::new())
1187 }
1188
1189 pub(crate) fn new(
1190 sections: Sections<CoreIndexSpace, CoreSectionType, CoreSection<Ast>>,
1191 ) -> Self {
1192 Self {
1193 sections,
1194 types: new_core_section_cache!(Type),
1195 func_type_refs: new_core_section_cache!(Func),
1196 codes: new_core_section_cache!(Code),
1197 tables: new_core_section_cache!(Table),
1198 mems: new_core_section_cache!(Mem),
1199 globals: new_core_section_cache!(Global),
1200 elems: new_core_section_cache!(Elem),
1201 datas: new_core_section_cache!(Data),
1202 start: new_core_section_cache!(Start),
1203 imports: new_core_section_cache!(Import),
1204 exports: new_core_section_cache!(Export),
1205 customs: new_core_section_cache!(Custom),
1206 type_index: SectionIndex::new(CoreIndexSpace::Type),
1207 func_index: SectionIndex::new(CoreIndexSpace::Func),
1208 code_index: SectionIndex::new(CoreIndexSpace::Code),
1209 table_index: SectionIndex::new(CoreIndexSpace::Table),
1210 mem_index: SectionIndex::new(CoreIndexSpace::Mem),
1211 global_index: SectionIndex::new(CoreIndexSpace::Global),
1212 elem_index: SectionIndex::new(CoreIndexSpace::Elem),
1213 data_index: SectionIndex::new(CoreIndexSpace::Data),
1214 export_index: SectionIndex::new(CoreIndexSpace::Export),
1215 }
1216 }
1217
1218 pub fn types(&self) -> Vec<Mrc<FuncType>> {
1220 self.types.populate(&self.sections);
1221 self.types.all()
1222 }
1223
1224 pub fn func_type_refs(&self) -> Vec<Mrc<FuncTypeRef>> {
1228 self.func_type_refs.populate(&self.sections);
1229 self.func_type_refs.all()
1230 }
1231
1232 pub fn codes(&self) -> Vec<Mrc<FuncCode<Ast::Expr>>> {
1236 self.codes.populate(&self.sections);
1237 self.codes.all()
1238 }
1239
1240 pub fn funcs(&self) -> Vec<Func<Ast::Expr>> {
1242 self.func_type_refs()
1243 .into_iter()
1244 .zip(self.codes())
1245 .map(|(func_type, code)| Func {
1246 type_idx: func_type.type_idx,
1247 code,
1248 })
1249 .collect()
1250 }
1251
1252 pub fn tables(&self) -> Vec<Mrc<Table>> {
1254 self.tables.populate(&self.sections);
1255 self.tables.all()
1256 }
1257
1258 pub fn mems(&self) -> Vec<Mrc<Mem>> {
1260 self.mems.populate(&self.sections);
1261 self.mems.all()
1262 }
1263
1264 pub fn globals(&self) -> Vec<Mrc<Global>> {
1266 self.globals.populate(&self.sections);
1267 self.globals.all()
1268 }
1269
1270 pub fn elems(&self) -> Vec<Mrc<Elem<Ast::Expr>>> {
1272 self.elems.populate(&self.sections);
1273 self.elems.all()
1274 }
1275
1276 pub fn datas(&self) -> Vec<Mrc<Ast::Data>> {
1278 self.datas.populate(&self.sections);
1279 self.datas.all()
1280 }
1281
1282 pub fn start(&self) -> Option<Mrc<Start>> {
1284 self.start.populate(&self.sections);
1285 self.start.all().pop()
1286 }
1287
1288 pub fn imports(&self) -> Vec<Mrc<Import>> {
1290 self.imports.populate(&self.sections);
1291 self.imports.all()
1292 }
1293
1294 pub fn exports(&self) -> Vec<Mrc<Export>> {
1296 self.exports.populate(&self.sections);
1297 self.exports.all()
1298 }
1299
1300 pub fn customs(&self) -> Vec<Mrc<Ast::Custom>> {
1302 self.customs.populate(&self.sections);
1303 self.customs.all()
1304 }
1305
1306 pub fn add_data(&mut self, data: Ast::Data) {
1308 self.datas.invalidate();
1309 self.data_index.invalidate();
1310 self.sections.add_to_last_group(CoreSection::Data(data));
1311 self.datas.populate(&self.sections);
1312 let count = self.datas.count();
1313 self.sections.clear_group(&CoreSectionType::DataCount);
1314 self.sections
1315 .add_to_last_group(CoreSection::DataCount(DataCount {
1316 count: (count + 1) as u32,
1317 }));
1318 }
1319
1320 pub fn add_elem(&mut self, elem: Elem<Ast::Expr>) {
1322 self.elems.invalidate();
1323 self.elem_index.invalidate();
1324 self.sections.add_to_last_group(CoreSection::Elem(elem));
1325 }
1326
1327 pub fn add_export(&mut self, export: Export) {
1329 self.exports.invalidate();
1330 self.export_index.invalidate();
1331 self.sections.add_to_last_group(CoreSection::Export(export));
1332 }
1333
1334 pub fn add_function(
1336 &mut self,
1337 func_type: FuncType,
1338 locals: Vec<ValType>,
1339 body: Ast::Expr,
1340 ) -> FuncIdx {
1341 let existing_type_idx = self.type_idx_of(&func_type);
1342 let type_idx = match existing_type_idx {
1343 Some(idx) => idx as TypeIdx,
1344 None => {
1345 let idx = self.types.count() as TypeIdx;
1346 self.types.invalidate();
1347 self.type_index.invalidate();
1348 self.sections
1349 .add_to_last_group(CoreSection::Type(func_type));
1350 idx
1351 }
1352 };
1353 let func_type_ref = FuncTypeRef { type_idx };
1354 let func_code = FuncCode { locals, body };
1355 self.codes.invalidate();
1356 self.code_index.invalidate();
1357 self.func_type_refs.invalidate();
1358 self.func_index.invalidate();
1359 self.sections
1360 .add_to_last_group(CoreSection::Func(func_type_ref));
1361 self.sections
1362 .add_to_last_group(CoreSection::Code(func_code));
1363 self.func_type_refs.populate(&self.sections);
1364 (self.func_type_refs.count() - 1) as FuncIdx
1365 }
1366
1367 pub fn add_global(&mut self, global: Global) {
1369 self.globals.invalidate();
1370 self.global_index.invalidate();
1371 self.sections.add_to_last_group(CoreSection::Global(global));
1372 }
1373
1374 pub fn add_memory(&mut self, mem: Mem) {
1376 self.mems.invalidate();
1377 self.mem_index.invalidate();
1378 self.sections.add_to_last_group(CoreSection::Mem(mem));
1379 }
1380
1381 pub fn add_table(&mut self, table: Table) {
1383 self.tables.invalidate();
1384 self.sections.add_to_last_group(CoreSection::Table(table));
1385 }
1386
1387 pub fn add_type(&mut self, func_type: FuncType) {
1389 self.types.invalidate();
1390 self.type_index.invalidate();
1391 self.sections
1392 .add_to_last_group(CoreSection::Type(func_type));
1393 }
1394
1395 pub fn get_code(&mut self, func_idx: FuncIdx) -> Option<Mrc<FuncCode<Ast::Expr>>> {
1397 self.code_index.populate(&self.sections);
1398 match self.code_index.get(&func_idx) {
1399 Some(section) => match &*section {
1400 CoreSection::Code(_) => Some(Mrc::map(section, |section| section.as_code())),
1401 _ => None,
1402 },
1403 None => None,
1404 }
1405 }
1406
1407 pub fn get_data(&mut self, data_idx: DataIdx) -> Option<Mrc<Ast::Data>> {
1409 self.data_index.populate(&self.sections);
1410 match self.data_index.get(&data_idx) {
1411 Some(section) => match &*section {
1412 CoreSection::Data(_) => Some(Mrc::map(section, |section| section.as_data())),
1413 _ => None,
1414 },
1415 _ => None,
1416 }
1417 }
1418
1419 pub fn get_elem(&mut self, elem_idx: ElemIdx) -> Option<Mrc<Elem<Ast::Expr>>> {
1421 self.elem_index.populate(&self.sections);
1422 match self.elem_index.get(&elem_idx) {
1423 Some(section) => match &*section {
1424 CoreSection::Elem(_) => Some(Mrc::map(section, |section| section.as_elem())),
1425 _ => None,
1426 },
1427 _ => None,
1428 }
1429 }
1430
1431 pub fn get_export(&mut self, export_idx: ExportIdx) -> Option<Mrc<Export>> {
1433 self.export_index.populate(&self.sections);
1434 match self.export_index.get(&export_idx) {
1435 Some(section) => match &*section {
1436 CoreSection::Export(_) => Some(Mrc::map(section, |section| section.as_export())),
1437 _ => None,
1438 },
1439 _ => None,
1440 }
1441 }
1442
1443 pub fn get_function(&mut self, func_idx: FuncIdx) -> Option<ImportOrFunc<Ast::Expr>> {
1447 self.func_index.populate(&self.sections);
1448 match self.func_index.get(&func_idx) {
1449 Some(section) => match &*section {
1450 CoreSection::Func(_) => {
1451 let code = self.get_code(func_idx).unwrap();
1452 let func_type_ref = section.as_func();
1453 let func = Func {
1454 type_idx: func_type_ref.type_idx,
1455 code,
1456 };
1457 Some(ImportOrFunc::Func(func))
1458 }
1459 CoreSection::Import(_) => {
1460 Some(ImportOrFunc::Import(Mrc::map(section, |section| {
1461 section.as_import()
1462 })))
1463 }
1464 _ => None,
1465 },
1466 _ => None,
1467 }
1468 }
1469
1470 pub fn get_global(&mut self, global_idx: GlobalIdx) -> Option<Mrc<Global>> {
1472 self.global_index.populate(&self.sections);
1473 match self.global_index.get(&global_idx) {
1474 Some(section) => match &*section {
1475 CoreSection::Global(_) => Some(Mrc::map(section, |section| section.as_global())),
1476 _ => None,
1477 },
1478 _ => None,
1479 }
1480 }
1481
1482 pub fn get_memory(&mut self, mem_idx: MemIdx) -> Option<Mrc<Mem>> {
1484 self.mem_index.populate(&self.sections);
1485 match self.mem_index.get(&mem_idx) {
1486 Some(section) => match &*section {
1487 CoreSection::Mem(_) => Some(Mrc::map(section, |section| section.as_mem())),
1488 _ => None,
1489 },
1490 _ => None,
1491 }
1492 }
1493
1494 pub fn get_table(&mut self, table_idx: TableIdx) -> Option<Mrc<Table>> {
1496 self.table_index.populate(&self.sections);
1497 match self.table_index.get(&table_idx) {
1498 Some(section) => match &*section {
1499 CoreSection::Table(_) => Some(Mrc::map(section, |section| section.as_table())),
1500 _ => None,
1501 },
1502 _ => None,
1503 }
1504 }
1505
1506 pub fn type_idx_of(&self, func_type: &FuncType) -> Option<TypeIdx> {
1508 self.types.populate(&self.sections);
1509 self.types
1510 .all()
1511 .into_iter()
1512 .position(|ft| *ft == *func_type)
1513 .map(|idx| idx as TypeIdx)
1514 }
1515
1516 pub fn into_sections(mut self) -> Vec<Mrc<CoreSection<Ast>>> {
1518 self.sections.take_all()
1519 }
1520
1521 pub fn into_grouped(self) -> Vec<(CoreSectionType, Vec<Mrc<CoreSection<Ast>>>)> {
1523 self.sections.into_grouped()
1524 }
1525}
1526
1527impl<Ast> Module<Ast>
1528where
1529 Ast: AstCustomization,
1530 Ast::Custom: RetainsCustomSection,
1531{
1532 #[cfg(feature = "metadata")]
1534 pub fn get_metadata(&self) -> Option<metadata::Metadata> {
1535 let mut producers = None;
1536 let mut name = None;
1537
1538 for custom in self.customs() {
1539 if custom.name() == "producers" {
1540 producers = wasm_metadata::Producers::from_bytes(custom.data(), 0).ok();
1541 } else if custom.name() == "name" {
1542 name = wasm_metadata::ModuleNames::from_bytes(custom.data(), 0)
1543 .ok()
1544 .and_then(|n| n.get_name().cloned());
1545 }
1546 }
1547
1548 if producers.is_some() || name.is_some() {
1549 Some(metadata::Metadata {
1550 name,
1551 producers: producers.map(|p| p.into()),
1552 })
1553 } else {
1554 None
1555 }
1556 }
1557}
1558
1559impl<Ast: AstCustomization> Debug for Module<Ast> {
1560 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
1561 self.sections.fmt(f)
1562 }
1563}
1564
1565impl<Ast: AstCustomization> PartialEq for Module<Ast> {
1566 fn eq(&self, other: &Self) -> bool {
1567 self.sections.eq(&other.sections)
1568 }
1569}
1570
1571impl<Ast: AstCustomization> From<Sections<CoreIndexSpace, CoreSectionType, CoreSection<Ast>>>
1572 for Module<Ast>
1573{
1574 fn from(value: Sections<CoreIndexSpace, CoreSectionType, CoreSection<Ast>>) -> Self {
1575 Self::new(value)
1576 }
1577}
1578
1579impl<Ast: AstCustomization> Clone for Module<Ast> {
1580 fn clone(&self) -> Self {
1581 Module::from(self.sections.clone())
1582 }
1583}
1584
1585#[cfg(feature = "component")]
1586impl<Ast: AstCustomization>
1587 Section<crate::component::ComponentIndexSpace, crate::component::ComponentSectionType>
1588 for Module<Ast>
1589{
1590 fn index_space(&self) -> crate::component::ComponentIndexSpace {
1591 crate::component::ComponentIndexSpace::Module
1592 }
1593
1594 fn section_type(&self) -> crate::component::ComponentSectionType {
1595 crate::component::ComponentSectionType::Module
1596 }
1597}