| 1 | mod aliases; | 
| 2 | mod builder; | 
|---|
| 3 | mod canonicals; | 
|---|
| 4 | mod components; | 
|---|
| 5 | mod exports; | 
|---|
| 6 | mod imports; | 
|---|
| 7 | mod instances; | 
|---|
| 8 | mod modules; | 
|---|
| 9 | mod names; | 
|---|
| 10 | mod start; | 
|---|
| 11 | mod types; | 
|---|
| 12 |  | 
|---|
| 13 | pub use self::aliases::*; | 
|---|
| 14 | pub use self::builder::*; | 
|---|
| 15 | pub use self::canonicals::*; | 
|---|
| 16 | pub use self::components::*; | 
|---|
| 17 | pub use self::exports::*; | 
|---|
| 18 | pub use self::imports::*; | 
|---|
| 19 | pub use self::instances::*; | 
|---|
| 20 | pub use self::modules::*; | 
|---|
| 21 | pub use self::names::*; | 
|---|
| 22 | pub use self::start::*; | 
|---|
| 23 | pub use self::types::*; | 
|---|
| 24 |  | 
|---|
| 25 | use crate::{CustomSection, Encode, ProducersSection, RawCustomSection}; | 
|---|
| 26 |  | 
|---|
| 27 | // Core sorts extended by the component model | 
|---|
| 28 | const CORE_TYPE_SORT: u8 = 0x10; | 
|---|
| 29 | const CORE_MODULE_SORT: u8 = 0x11; | 
|---|
| 30 | const CORE_INSTANCE_SORT: u8 = 0x12; | 
|---|
| 31 |  | 
|---|
| 32 | const CORE_SORT: u8 = 0x00; | 
|---|
| 33 | const FUNCTION_SORT: u8 = 0x01; | 
|---|
| 34 | const VALUE_SORT: u8 = 0x02; | 
|---|
| 35 | const TYPE_SORT: u8 = 0x03; | 
|---|
| 36 | const COMPONENT_SORT: u8 = 0x04; | 
|---|
| 37 | const INSTANCE_SORT: u8 = 0x05; | 
|---|
| 38 |  | 
|---|
| 39 | /// A WebAssembly component section. | 
|---|
| 40 | /// | 
|---|
| 41 | /// Various builders defined in this crate already implement this trait, but you | 
|---|
| 42 | /// can also implement it yourself for your own custom section builders, or use | 
|---|
| 43 | /// `RawSection` to use a bunch of raw bytes as a section. | 
|---|
| 44 | pub trait ComponentSection: Encode { | 
|---|
| 45 | /// Gets the section identifier for this section. | 
|---|
| 46 | fn id(&self) -> u8; | 
|---|
| 47 |  | 
|---|
| 48 | /// Appends this section to the specified destination list of bytes. | 
|---|
| 49 | fn append_to_component(&self, dst: &mut Vec<u8>) { | 
|---|
| 50 | dst.push(self.id()); | 
|---|
| 51 | self.encode(sink:dst); | 
|---|
| 52 | } | 
|---|
| 53 | } | 
|---|
| 54 |  | 
|---|
| 55 | /// Known section identifiers of WebAssembly components. | 
|---|
| 56 | /// | 
|---|
| 57 | /// These sections are supported by the component model proposal. | 
|---|
| 58 | #[ derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd)] | 
|---|
| 59 | #[ repr(u8)] | 
|---|
| 60 | pub enum ComponentSectionId { | 
|---|
| 61 | /// The section is a core custom section. | 
|---|
| 62 | CoreCustom = 0, | 
|---|
| 63 | /// The section is a core module section. | 
|---|
| 64 | CoreModule = 1, | 
|---|
| 65 | /// The section is a core instance section. | 
|---|
| 66 | CoreInstance = 2, | 
|---|
| 67 | /// The section is a core type section. | 
|---|
| 68 | CoreType = 3, | 
|---|
| 69 | /// The section is a component section. | 
|---|
| 70 | Component = 4, | 
|---|
| 71 | /// The section is an instance section. | 
|---|
| 72 | Instance = 5, | 
|---|
| 73 | /// The section is an alias section. | 
|---|
| 74 | Alias = 6, | 
|---|
| 75 | /// The section is a type section. | 
|---|
| 76 | Type = 7, | 
|---|
| 77 | /// The section is a canonical function section. | 
|---|
| 78 | CanonicalFunction = 8, | 
|---|
| 79 | /// The section is a start section. | 
|---|
| 80 | Start = 9, | 
|---|
| 81 | /// The section is an import section. | 
|---|
| 82 | Import = 10, | 
|---|
| 83 | /// The section is an export section. | 
|---|
| 84 | Export = 11, | 
|---|
| 85 | } | 
|---|
| 86 |  | 
|---|
| 87 | impl From<ComponentSectionId> for u8 { | 
|---|
| 88 | #[ inline] | 
|---|
| 89 | fn from(id: ComponentSectionId) -> u8 { | 
|---|
| 90 | id as u8 | 
|---|
| 91 | } | 
|---|
| 92 | } | 
|---|
| 93 |  | 
|---|
| 94 | impl Encode for ComponentSectionId { | 
|---|
| 95 | fn encode(&self, sink: &mut Vec<u8>) { | 
|---|
| 96 | sink.push(*self as u8); | 
|---|
| 97 | } | 
|---|
| 98 | } | 
|---|
| 99 |  | 
|---|
| 100 | /// Represents a WebAssembly component that is being encoded. | 
|---|
| 101 | /// | 
|---|
| 102 | /// Unlike core WebAssembly modules, the sections of a component | 
|---|
| 103 | /// may appear in any order and may be repeated. | 
|---|
| 104 | /// | 
|---|
| 105 | /// Components may also added as a section to other components. | 
|---|
| 106 | #[ derive(Clone, Debug)] | 
|---|
| 107 | pub struct Component { | 
|---|
| 108 | bytes: Vec<u8>, | 
|---|
| 109 | } | 
|---|
| 110 |  | 
|---|
| 111 | impl Component { | 
|---|
| 112 | /// The 8-byte header at the beginning of all components. | 
|---|
| 113 | #[rustfmt::skip] | 
|---|
| 114 | pub const HEADER: [u8; 8] = [ | 
|---|
| 115 | // Magic | 
|---|
| 116 | 0x00, 0x61, 0x73, 0x6D, | 
|---|
| 117 | // Version | 
|---|
| 118 | 0x0d, 0x00, 0x01, 0x00, | 
|---|
| 119 | ]; | 
|---|
| 120 |  | 
|---|
| 121 | /// Begin writing a new `Component`. | 
|---|
| 122 | pub fn new() -> Self { | 
|---|
| 123 | Self { | 
|---|
| 124 | bytes: Self::HEADER.to_vec(), | 
|---|
| 125 | } | 
|---|
| 126 | } | 
|---|
| 127 |  | 
|---|
| 128 | /// Finish writing this component and extract ownership of the encoded bytes. | 
|---|
| 129 | pub fn finish(self) -> Vec<u8> { | 
|---|
| 130 | self.bytes | 
|---|
| 131 | } | 
|---|
| 132 |  | 
|---|
| 133 | /// Write a section to this component. | 
|---|
| 134 | pub fn section(&mut self, section: &impl ComponentSection) -> &mut Self { | 
|---|
| 135 | self.bytes.push(section.id()); | 
|---|
| 136 | section.encode(&mut self.bytes); | 
|---|
| 137 | self | 
|---|
| 138 | } | 
|---|
| 139 |  | 
|---|
| 140 | /// View the encoded bytes. | 
|---|
| 141 | pub fn as_slice(&self) -> &[u8] { | 
|---|
| 142 | &self.bytes | 
|---|
| 143 | } | 
|---|
| 144 | } | 
|---|
| 145 |  | 
|---|
| 146 | impl Default for Component { | 
|---|
| 147 | fn default() -> Self { | 
|---|
| 148 | Self::new() | 
|---|
| 149 | } | 
|---|
| 150 | } | 
|---|
| 151 |  | 
|---|
| 152 | impl ComponentSection for CustomSection<'_> { | 
|---|
| 153 | fn id(&self) -> u8 { | 
|---|
| 154 | ComponentSectionId::CoreCustom.into() | 
|---|
| 155 | } | 
|---|
| 156 | } | 
|---|
| 157 |  | 
|---|
| 158 | impl ComponentSection for RawCustomSection<'_> { | 
|---|
| 159 | fn id(&self) -> u8 { | 
|---|
| 160 | ComponentSectionId::CoreCustom.into() | 
|---|
| 161 | } | 
|---|
| 162 | } | 
|---|
| 163 |  | 
|---|
| 164 | impl ComponentSection for ProducersSection { | 
|---|
| 165 | fn id(&self) -> u8 { | 
|---|
| 166 | ComponentSectionId::CoreCustom.into() | 
|---|
| 167 | } | 
|---|
| 168 | } | 
|---|
| 169 |  | 
|---|