1 | use crate::{BinaryReader, ComponentExternalKind, ExternalKind, FromReader, Result}; |
2 | |
3 | /// Represents the kind of an outer alias in a WebAssembly component. |
4 | #[derive (Clone, Copy, Debug, Eq, PartialEq)] |
5 | pub enum ComponentOuterAliasKind { |
6 | /// The alias is to a core module. |
7 | CoreModule, |
8 | /// The alias is to a core type. |
9 | CoreType, |
10 | /// The alias is to a component type. |
11 | Type, |
12 | /// The alias is to a component. |
13 | Component, |
14 | } |
15 | |
16 | /// Represents an alias in a WebAssembly component. |
17 | #[derive (Debug, Clone, Eq, PartialEq)] |
18 | pub enum ComponentAlias<'a> { |
19 | /// The alias is to an export of a component instance. |
20 | InstanceExport { |
21 | /// The alias kind. |
22 | kind: ComponentExternalKind, |
23 | /// The instance index. |
24 | instance_index: u32, |
25 | /// The export name. |
26 | name: &'a str, |
27 | }, |
28 | /// The alias is to an export of a module instance. |
29 | CoreInstanceExport { |
30 | /// The alias kind. |
31 | kind: ExternalKind, |
32 | /// The instance index. |
33 | instance_index: u32, |
34 | /// The export name. |
35 | name: &'a str, |
36 | }, |
37 | /// The alias is to an outer item. |
38 | Outer { |
39 | /// The alias kind. |
40 | kind: ComponentOuterAliasKind, |
41 | /// The outward count, starting at zero for the current component. |
42 | count: u32, |
43 | /// The index of the item within the outer component. |
44 | index: u32, |
45 | }, |
46 | } |
47 | |
48 | /// Section reader for the component alias section |
49 | pub type ComponentAliasSectionReader<'a> = crate::SectionLimited<'a, ComponentAlias<'a>>; |
50 | |
51 | impl<'a> FromReader<'a> for ComponentAlias<'a> { |
52 | fn from_reader(reader: &mut BinaryReader<'a>) -> Result<Self> { |
53 | // We don't know what type of alias it is yet, so just read the sort bytes |
54 | let offset = reader.original_position(); |
55 | let byte1 = reader.read_u8()?; |
56 | let byte2 = if byte1 == 0x00 { |
57 | Some(reader.read_u8()?) |
58 | } else { |
59 | None |
60 | }; |
61 | |
62 | Ok(match reader.read_u8()? { |
63 | 0x00 => ComponentAlias::InstanceExport { |
64 | kind: ComponentExternalKind::from_bytes(byte1, byte2, offset)?, |
65 | instance_index: reader.read_var_u32()?, |
66 | name: reader.read_string()?, |
67 | }, |
68 | 0x01 => ComponentAlias::CoreInstanceExport { |
69 | kind: BinaryReader::external_kind_from_byte( |
70 | byte2.ok_or_else(|| { |
71 | BinaryReader::invalid_leading_byte_error( |
72 | byte1, |
73 | "core instance export kind" , |
74 | offset, |
75 | ) |
76 | })?, |
77 | offset, |
78 | )?, |
79 | instance_index: reader.read_var_u32()?, |
80 | name: reader.read_string()?, |
81 | }, |
82 | 0x02 => ComponentAlias::Outer { |
83 | kind: component_outer_alias_kind_from_bytes(byte1, byte2, offset)?, |
84 | count: reader.read_var_u32()?, |
85 | index: reader.read_var_u32()?, |
86 | }, |
87 | x => reader.invalid_leading_byte(x, "alias" )?, |
88 | }) |
89 | } |
90 | } |
91 | |
92 | fn component_outer_alias_kind_from_bytes( |
93 | byte1: u8, |
94 | byte2: Option<u8>, |
95 | offset: usize, |
96 | ) -> Result<ComponentOuterAliasKind> { |
97 | Ok(match byte1 { |
98 | 0x00 => match byte2.unwrap() { |
99 | 0x10 => ComponentOuterAliasKind::CoreType, |
100 | 0x11 => ComponentOuterAliasKind::CoreModule, |
101 | x: u8 => { |
102 | return Err(BinaryReader::invalid_leading_byte_error( |
103 | byte:x, |
104 | desc:"component outer alias kind" , |
105 | offset:offset + 1, |
106 | )) |
107 | } |
108 | }, |
109 | 0x03 => ComponentOuterAliasKind::Type, |
110 | 0x04 => ComponentOuterAliasKind::Component, |
111 | x: u8 => { |
112 | return Err(BinaryReader::invalid_leading_byte_error( |
113 | byte:x, |
114 | desc:"component outer alias kind" , |
115 | offset, |
116 | )) |
117 | } |
118 | }) |
119 | } |
120 | |