| 1 | use crate::{ |
| 2 | BinaryReader, ComponentExternalKind, ComponentValType, FromReader, Result, SectionLimited, |
| 3 | }; |
| 4 | |
| 5 | /// Represents the type bounds for imports and exports. |
| 6 | #[derive (Clone, Copy, Debug, Eq, PartialEq)] |
| 7 | pub enum TypeBounds { |
| 8 | /// The type is bounded by equality. |
| 9 | Eq(u32), |
| 10 | /// A fresh resource type, |
| 11 | SubResource, |
| 12 | } |
| 13 | |
| 14 | impl<'a> FromReader<'a> for TypeBounds { |
| 15 | fn from_reader(reader: &mut BinaryReader<'a>) -> Result<Self> { |
| 16 | Ok(match reader.read_u8()? { |
| 17 | 0x00 => TypeBounds::Eq(reader.read()?), |
| 18 | 0x01 => TypeBounds::SubResource, |
| 19 | x: u8 => return reader.invalid_leading_byte(byte:x, desc:"type bound" ), |
| 20 | }) |
| 21 | } |
| 22 | } |
| 23 | |
| 24 | /// Represents a reference to a component type. |
| 25 | #[derive (Clone, Copy, Debug, Eq, PartialEq)] |
| 26 | pub enum ComponentTypeRef { |
| 27 | /// The reference is to a core module type. |
| 28 | /// |
| 29 | /// The index is expected to be core type index to a core module type. |
| 30 | Module(u32), |
| 31 | /// The reference is to a function type. |
| 32 | /// |
| 33 | /// The index is expected to be a type index to a function type. |
| 34 | Func(u32), |
| 35 | /// The reference is to a value type. |
| 36 | Value(ComponentValType), |
| 37 | /// The reference is to a bounded type. |
| 38 | /// |
| 39 | /// The index is expected to be a type index. |
| 40 | Type(TypeBounds), |
| 41 | /// The reference is to an instance type. |
| 42 | /// |
| 43 | /// The index is a type index to an instance type. |
| 44 | Instance(u32), |
| 45 | /// The reference is to a component type. |
| 46 | /// |
| 47 | /// The index is a type index to a component type. |
| 48 | Component(u32), |
| 49 | } |
| 50 | |
| 51 | impl ComponentTypeRef { |
| 52 | /// Returns the corresponding [`ComponentExternalKind`] for this reference. |
| 53 | pub fn kind(&self) -> ComponentExternalKind { |
| 54 | match self { |
| 55 | ComponentTypeRef::Module(_) => ComponentExternalKind::Module, |
| 56 | ComponentTypeRef::Func(_) => ComponentExternalKind::Func, |
| 57 | ComponentTypeRef::Value(_) => ComponentExternalKind::Value, |
| 58 | ComponentTypeRef::Type(..) => ComponentExternalKind::Type, |
| 59 | ComponentTypeRef::Instance(_) => ComponentExternalKind::Instance, |
| 60 | ComponentTypeRef::Component(_) => ComponentExternalKind::Component, |
| 61 | } |
| 62 | } |
| 63 | } |
| 64 | |
| 65 | impl<'a> FromReader<'a> for ComponentTypeRef { |
| 66 | fn from_reader(reader: &mut BinaryReader<'a>) -> Result<Self> { |
| 67 | Ok(match reader.read()? { |
| 68 | ComponentExternalKind::Module => ComponentTypeRef::Module(reader.read()?), |
| 69 | ComponentExternalKind::Func => ComponentTypeRef::Func(reader.read()?), |
| 70 | ComponentExternalKind::Value => ComponentTypeRef::Value(reader.read()?), |
| 71 | ComponentExternalKind::Type => ComponentTypeRef::Type(reader.read()?), |
| 72 | ComponentExternalKind::Instance => ComponentTypeRef::Instance(reader.read()?), |
| 73 | ComponentExternalKind::Component => ComponentTypeRef::Component(reader.read()?), |
| 74 | }) |
| 75 | } |
| 76 | } |
| 77 | |
| 78 | /// Represents an import in a WebAssembly component |
| 79 | #[derive (Debug, Copy, Clone, Eq, PartialEq)] |
| 80 | pub struct ComponentImport<'a> { |
| 81 | /// The name of the imported item. |
| 82 | pub name: ComponentImportName<'a>, |
| 83 | /// The type reference for the import. |
| 84 | pub ty: ComponentTypeRef, |
| 85 | } |
| 86 | |
| 87 | impl<'a> FromReader<'a> for ComponentImport<'a> { |
| 88 | fn from_reader(reader: &mut BinaryReader<'a>) -> Result<Self> { |
| 89 | Ok(ComponentImport { |
| 90 | name: reader.read()?, |
| 91 | ty: reader.read()?, |
| 92 | }) |
| 93 | } |
| 94 | } |
| 95 | |
| 96 | /// A reader for the import section of a WebAssembly component. |
| 97 | /// |
| 98 | /// # Examples |
| 99 | /// |
| 100 | /// ``` |
| 101 | /// use wasmparser::{ComponentImportSectionReader, BinaryReader}; |
| 102 | /// let data: &[u8] = &[0x01, 0x00, 0x01, 0x41, 0x01, 0x66]; |
| 103 | /// let reader = BinaryReader::new(data, 0); |
| 104 | /// let reader = ComponentImportSectionReader::new(reader).unwrap(); |
| 105 | /// for import in reader { |
| 106 | /// let import = import.expect("import" ); |
| 107 | /// println!("Import: {:?}" , import); |
| 108 | /// } |
| 109 | /// ``` |
| 110 | pub type ComponentImportSectionReader<'a> = SectionLimited<'a, ComponentImport<'a>>; |
| 111 | |
| 112 | /// Represents the name of a component import. |
| 113 | #[derive (Debug, Copy, Clone, Eq, PartialEq)] |
| 114 | #[allow (missing_docs)] |
| 115 | pub struct ComponentImportName<'a>(pub &'a str); |
| 116 | |
| 117 | impl<'a> FromReader<'a> for ComponentImportName<'a> { |
| 118 | fn from_reader(reader: &mut BinaryReader<'a>) -> Result<Self> { |
| 119 | match reader.read_u8()? { |
| 120 | // This is the spec-required byte as of this time. |
| 121 | 0x00 => {} |
| 122 | |
| 123 | // Prior to WebAssembly/component-model#263 export names used a |
| 124 | // discriminator byte of 0x01 to indicate an "interface" of the |
| 125 | // form `a:b/c` but nowadays that's inferred from string syntax. |
| 126 | // Ignore 0-vs-1 to continue to parse older binaries. Eventually |
| 127 | // this will go away. |
| 128 | // |
| 129 | // This logic to ignore 0x01 was landed on 2023-10-28 in |
| 130 | // bytecodealliance/wasm-tools#1262 and the encoder at the time |
| 131 | // still emitted 0x01 to have better compatibility with prior |
| 132 | // validators. |
| 133 | // |
| 134 | // On 2024-09-03 in bytecodealliance/wasm-tools#TODO the encoder |
| 135 | // was updated to always emit 0x00 as a leading byte. After enough |
| 136 | // time has passed this case may be able to be removed. When |
| 137 | // removing this it's probably best to do it with a `WasmFeatures` |
| 138 | // flag first to ensure there's an opt-in way of fixing things. |
| 139 | 0x01 => {} |
| 140 | |
| 141 | x => return reader.invalid_leading_byte(x, "import name" ), |
| 142 | } |
| 143 | Ok(ComponentImportName(reader.read_string()?)) |
| 144 | } |
| 145 | } |
| 146 | |