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