tinywasm_wasmparser/readers/component/canonicals.rs
1use alloc::boxed::Box;
2
3use crate::limits::MAX_WASM_CANONICAL_OPTIONS;
4use crate::{BinaryReader, FromReader, Result, SectionLimited};
5
6/// Represents options for component functions.
7#[derive(Debug, Clone, Copy, PartialEq, Eq)]
8pub enum CanonicalOption {
9 /// The string types in the function signature are UTF-8 encoded.
10 UTF8,
11 /// The string types in the function signature are UTF-16 encoded.
12 UTF16,
13 /// The string types in the function signature are compact UTF-16 encoded.
14 CompactUTF16,
15 /// The memory to use if the lifting or lowering of a function requires memory access.
16 ///
17 /// The value is an index to a core memory.
18 Memory(u32),
19 /// The realloc function to use if the lifting or lowering of a function requires memory
20 /// allocation.
21 ///
22 /// The value is an index to a core function of type `(func (param i32 i32 i32 i32) (result i32))`.
23 Realloc(u32),
24 /// The post-return function to use if the lifting of a function requires
25 /// cleanup after the function returns.
26 PostReturn(u32),
27}
28
29/// Represents a canonical function in a WebAssembly component.
30#[derive(Debug, Clone)]
31pub enum CanonicalFunction {
32 /// The function lifts a core WebAssembly function to the canonical ABI.
33 Lift {
34 /// The index of the core WebAssembly function to lift.
35 core_func_index: u32,
36 /// The index of the lifted function's type.
37 type_index: u32,
38 /// The canonical options for the function.
39 options: Box<[CanonicalOption]>,
40 },
41 /// The function lowers a canonical ABI function to a core WebAssembly function.
42 Lower {
43 /// The index of the function to lower.
44 func_index: u32,
45 /// The canonical options for the function.
46 options: Box<[CanonicalOption]>,
47 },
48 /// A function which creates a new owned handle to a resource.
49 ResourceNew {
50 /// The type index of the resource that's being created.
51 resource: u32,
52 },
53 /// A function which is used to drop resource handles of the specified type.
54 ResourceDrop {
55 /// The type index of the resource that's being dropped.
56 resource: u32,
57 },
58 /// A function which returns the underlying i32-based representation of the
59 /// specified resource.
60 ResourceRep {
61 /// The type index of the resource that's being accessed.
62 resource: u32,
63 },
64}
65
66/// A reader for the canonical section of a WebAssembly component.
67pub type ComponentCanonicalSectionReader<'a> = SectionLimited<'a, CanonicalFunction>;
68
69impl<'a> FromReader<'a> for CanonicalFunction {
70 fn from_reader(reader: &mut BinaryReader<'a>) -> Result<CanonicalFunction> {
71 Ok(match reader.read_u8()? {
72 0x00 => match reader.read_u8()? {
73 0x00 => {
74 let core_func_index = reader.read_var_u32()?;
75 let options = reader
76 .read_iter(MAX_WASM_CANONICAL_OPTIONS, "canonical options")?
77 .collect::<Result<_>>()?;
78 let type_index = reader.read_var_u32()?;
79 CanonicalFunction::Lift {
80 core_func_index,
81 options,
82 type_index,
83 }
84 }
85 x => return reader.invalid_leading_byte(x, "canonical function lift"),
86 },
87 0x01 => match reader.read_u8()? {
88 0x00 => CanonicalFunction::Lower {
89 func_index: reader.read_var_u32()?,
90 options: reader
91 .read_iter(MAX_WASM_CANONICAL_OPTIONS, "canonical options")?
92 .collect::<Result<_>>()?,
93 },
94 x => return reader.invalid_leading_byte(x, "canonical function lower"),
95 },
96 0x02 => CanonicalFunction::ResourceNew {
97 resource: reader.read()?,
98 },
99 0x03 => CanonicalFunction::ResourceDrop {
100 resource: reader.read()?,
101 },
102 0x04 => CanonicalFunction::ResourceRep {
103 resource: reader.read()?,
104 },
105 x => return reader.invalid_leading_byte(x, "canonical function"),
106 })
107 }
108}
109
110impl<'a> FromReader<'a> for CanonicalOption {
111 fn from_reader(reader: &mut BinaryReader<'a>) -> Result<Self> {
112 Ok(match reader.read_u8()? {
113 0x00 => CanonicalOption::UTF8,
114 0x01 => CanonicalOption::UTF16,
115 0x02 => CanonicalOption::CompactUTF16,
116 0x03 => CanonicalOption::Memory(reader.read_var_u32()?),
117 0x04 => CanonicalOption::Realloc(reader.read_var_u32()?),
118 0x05 => CanonicalOption::PostReturn(reader.read_var_u32()?),
119 x => return reader.invalid_leading_byte(x, "canonical option"),
120 })
121 }
122}