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