sophon_wasm/elements/
func.rs

1use std::io;
2use super::{
3    Deserialize, Error, ValueType, VarUint32, CountedList, Opcodes,
4    Serialize, CountedWriter, CountedListWriter,
5};
6
7/// Function signature (type reference)
8#[derive(Clone)]
9pub struct Func(u32);
10
11impl Func {
12    /// New function signature
13    pub fn new(type_ref: u32) -> Self { Func(type_ref) }
14
15    /// Function signature type reference.
16    pub fn type_ref(&self) -> u32 {
17        self.0
18    }
19
20    /// Function signature type reference (mutable).
21    pub fn type_ref_mut(&mut self) -> &mut u32 {
22        &mut self.0
23    }
24}
25
26/// Local definition inside the function body.
27#[derive(Debug, Clone)]
28pub struct Local {
29    count: u32,
30    value_type: ValueType,
31}
32
33impl Local {
34    /// New local with `count` and `value_type`.
35    pub fn new(count: u32, value_type: ValueType) -> Self {
36        Local { count: count, value_type: value_type }
37    }
38
39    /// Number of locals with the shared type.
40    pub fn count(&self) -> u32 { self.count }
41
42    /// Type of the locals.
43    pub fn value_type(&self) -> ValueType { self.value_type }
44}
45
46impl Deserialize for Local {
47     type Error = Error;
48
49    fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
50        let count = VarUint32::deserialize(reader)?;
51        let value_type = ValueType::deserialize(reader)?;
52        Ok(Local { count: count.into(), value_type: value_type })
53    }
54}
55
56impl Serialize for Local {
57    type Error = Error;
58
59    fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
60        VarUint32::from(self.count).serialize(writer)?;
61        self.value_type.serialize(writer)?;
62        Ok(())
63    }
64}
65
66/// Function body definition.
67#[derive(Debug, Clone)]
68pub struct FuncBody {
69    locals: Vec<Local>,
70    opcodes: Opcodes,
71}
72
73impl FuncBody {
74    /// New function body with given `locals` and `opcodes`
75    pub fn new(locals: Vec<Local>, opcodes: Opcodes) -> Self {
76        FuncBody { locals: locals, opcodes: opcodes }
77    }
78
79    /// List of individual opcodes
80    pub fn empty() -> Self {
81        FuncBody { locals: Vec::new(), opcodes: Opcodes::empty() }
82    }
83
84    /// Locals declared in function body.
85    pub fn locals(&self) -> &[Local] { &self.locals }
86
87    /// Opcode sequence of the function body. Minimal opcode sequence
88    /// is just `&[Opcode::End]`
89    pub fn code(&self) -> &Opcodes { &self.opcodes }
90
91    /// Locals declared in function body (mutable).
92    pub fn locals_mut(&mut self) -> &mut Vec<Local> { &mut self.locals }
93
94    /// Opcode sequence of the function body (mutable).
95    pub fn code_mut(&mut self) -> &mut Opcodes { &mut self.opcodes }
96}
97
98impl Deserialize for FuncBody {
99     type Error = Error;
100
101    fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
102        // todo: maybe use reader.take(section_length)
103        let _body_size = VarUint32::deserialize(reader)?;
104        let locals: Vec<Local> = CountedList::deserialize(reader)?.into_inner();
105        let opcodes = Opcodes::deserialize(reader)?;
106        Ok(FuncBody { locals: locals, opcodes: opcodes })
107    }
108}
109
110impl Serialize for FuncBody {
111    type Error = Error;
112
113    fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
114        let mut counted_writer = CountedWriter::new(writer);
115
116        let data = self.locals;
117        let counted_list = CountedListWriter::<Local, _>(
118            data.len(),
119            data.into_iter().map(Into::into),
120        );
121        counted_list.serialize(&mut counted_writer)?;
122
123        let code = self.opcodes;
124        code.serialize(&mut counted_writer)?;
125
126        counted_writer.done()?;
127
128        Ok(())
129    }
130}