sophon_wasm/builder/
code.rs

1use elements;
2use super::invoke::{Invoke, Identity};
3use super::misc::{ValueTypeBuilder, ValueTypesBuilder, OptionalValueTypeBuilder};
4
5pub enum Signature {
6    TypeReference(u32),
7    Inline(elements::FunctionType),
8}
9
10pub struct SignatureBuilder<F=Identity> {
11    callback: F,
12    signature: elements::FunctionType,
13}
14
15impl SignatureBuilder {
16    pub fn new() -> Self {
17        SignatureBuilder::with_callback(Identity)
18    }
19}
20
21impl<F> SignatureBuilder<F> where F: Invoke<elements::FunctionType> {
22    pub fn with_callback(callback: F) -> Self {
23        SignatureBuilder { 
24            callback: callback, 
25            signature: elements::FunctionType::default(),
26        }
27    }
28
29    pub fn with_param(mut self, value_type: elements::ValueType) -> Self {
30        self.signature.params_mut().push(value_type);
31        self
32    }
33
34    pub fn with_params(mut self, value_types: Vec<elements::ValueType>) -> Self {
35        self.signature.params_mut().extend(value_types);
36        self
37    }
38
39    pub fn with_return_type(mut self, return_type: Option<elements::ValueType>) -> Self {
40        *self.signature.return_type_mut() = return_type;
41        self
42    }
43
44    pub fn param(self) -> ValueTypeBuilder<Self> {
45        ValueTypeBuilder::with_callback(self)
46    }
47
48    pub fn params(self) -> ValueTypesBuilder<Self> {
49        ValueTypesBuilder::with_callback(self)
50    }
51
52    pub fn return_type(self) -> OptionalValueTypeBuilder<Self> {
53        OptionalValueTypeBuilder::with_callback(self)
54    }
55
56    pub fn build(self) -> F::Result {
57        self.callback.invoke(self.signature)
58    }
59
60    pub fn build_sig(self) -> Signature {
61        Signature::Inline(self.signature)
62    }
63}
64
65impl<F> Invoke<Vec<elements::ValueType>> for SignatureBuilder<F>
66    where F: Invoke<elements::FunctionType>
67{
68    type Result = Self;
69
70    fn invoke(self, args: Vec<elements::ValueType>) -> Self {
71        self.with_params(args)
72    }
73}
74
75impl<F> Invoke<Option<elements::ValueType>> for SignatureBuilder<F>
76    where F: Invoke<elements::FunctionType>
77{
78    type Result = Self;
79
80    fn invoke(self, arg: Option<elements::ValueType>) -> Self {
81        self.with_return_type(arg)
82    }
83}
84
85impl<F> Invoke<elements::ValueType> for SignatureBuilder<F> 
86    where F: Invoke<elements::FunctionType>  
87{
88    type Result = Self;
89
90    fn invoke(self, arg: elements::ValueType) -> Self {
91        self.with_param(arg)
92    }
93}
94
95pub struct TypeRefBuilder<F=Identity> {
96    callback: F,
97    type_ref: u32,
98}
99
100impl<F> TypeRefBuilder<F> where F: Invoke<u32> {
101    pub fn with_callback(callback: F) -> Self {
102        TypeRefBuilder { 
103            callback: callback, 
104            type_ref: 0
105        }
106    }
107
108    pub fn val(mut self, val: u32) -> Self {
109        self.type_ref = val;
110        self
111    }
112
113    pub fn build(self) -> F::Result { self.callback.invoke(self.type_ref) }
114}
115
116pub struct SignaturesBuilder<F=Identity> {
117    callback: F,
118    section: Vec<Signature>,
119}
120
121impl SignaturesBuilder {
122    /// New empty functions section builder
123    pub fn new() -> Self {
124        SignaturesBuilder::with_callback(Identity)
125    }
126}
127
128impl<F> SignaturesBuilder<F> {
129    pub fn with_callback(callback: F) -> Self {
130        SignaturesBuilder {
131            callback: callback,
132            section: Vec::new(),
133        }
134    }
135
136    pub fn with_signature(mut self, signature: Signature) -> Self {
137        self.section.push(signature);
138        self
139    }
140
141    pub fn type_ref(self) -> TypeRefBuilder<Self> {
142        TypeRefBuilder::with_callback(self)
143    }    
144}
145
146impl<F> SignaturesBuilder<F> where F: Invoke<SignatureBindings> {
147    pub fn signature(self) -> SignatureBuilder<Self> {
148        SignatureBuilder::with_callback(self)
149    }
150}
151
152impl<F> Invoke<elements::FunctionType> for SignaturesBuilder<F> {
153	type Result = Self;
154
155	fn invoke(self, signature: elements::FunctionType) -> Self {
156		self.with_signature(Signature::Inline(signature))
157    }    
158}
159
160impl<F> Invoke<u32> for SignaturesBuilder<F> {
161	type Result = Self;
162
163	fn invoke(self, type_ref: u32) -> Self {
164		self.with_signature(Signature::TypeReference(type_ref))
165    }    
166}
167
168impl<F> SignaturesBuilder<F> where F: Invoke<elements::FunctionSection> {
169    pub fn build(self) -> F::Result {
170        let mut result = elements::FunctionSection::default();
171        for f in self.section.into_iter() {
172            if let Signature::TypeReference(type_ref) = f {
173                result.entries_mut().push(elements::Func::new(type_ref));
174            } else {
175                unreachable!(); // never possible with current generics impl-s
176            }
177        }
178        self.callback.invoke(result)
179    }
180}
181
182pub type SignatureBindings = Vec<Signature>;
183
184impl<F> SignaturesBuilder<F> where F: Invoke<SignatureBindings> {
185    pub fn bind(self) -> F::Result {
186        self.callback.invoke(self.section)
187    }
188}
189
190pub struct FuncBodyBuilder<F=Identity> {
191    callback: F,
192    body: elements::FuncBody,
193}
194
195impl<F> FuncBodyBuilder<F> {
196    pub fn with_callback(callback: F) -> Self {
197        FuncBodyBuilder {
198            callback: callback,
199            body: elements::FuncBody::new(Vec::new(), elements::Opcodes::empty()),
200        }
201    }
202}
203
204impl<F> FuncBodyBuilder<F> where F: Invoke<elements::FuncBody> {
205    pub fn with_func(mut self, func: elements::FuncBody) -> Self {
206        self.body = func;
207        self
208    }
209
210    pub fn with_locals(mut self, locals: Vec<elements::Local>) -> Self {
211        self.body.locals_mut().extend(locals);
212        self
213    }
214
215    pub fn with_opcodes(mut self, opcodes: elements::Opcodes) -> Self {
216        *self.body.code_mut() = opcodes;
217        self
218    }
219
220    pub fn build(self) -> F::Result {
221        self.callback.invoke(self.body)
222    }
223}
224
225pub struct FunctionDefinition {
226    pub is_main: bool,
227    pub signature: Signature,
228    pub code: elements::FuncBody,
229}
230
231impl Default for FunctionDefinition {
232    fn default() -> Self {
233        FunctionDefinition {
234            is_main: false,
235            signature: Signature::TypeReference(0),
236            code: elements::FuncBody::empty(),
237        }
238    }
239}
240
241pub struct FunctionBuilder<F=Identity> {
242    callback: F,
243    func: FunctionDefinition,
244}
245
246impl FunctionBuilder {
247    pub fn new() -> Self {
248        FunctionBuilder::with_callback(Identity)
249    }
250}
251
252impl<F> FunctionBuilder<F> where F: Invoke<FunctionDefinition> {
253    pub fn with_callback(callback: F) -> Self {
254        FunctionBuilder {
255            callback: callback,
256            func: Default::default(),
257        }
258    }
259
260    pub fn main(mut self) -> Self {
261        self.func.is_main = true;
262        self
263    }
264
265    pub fn signature(self) -> SignatureBuilder<Self> {
266        SignatureBuilder::with_callback(self)
267    }
268
269    pub fn with_signature(mut self, signature: Signature) -> Self {
270        self.func.signature = signature;
271        self
272    }
273
274    pub fn body(self) -> FuncBodyBuilder<Self> {
275        FuncBodyBuilder::with_callback(self)
276    }
277
278    pub fn with_body(mut self, body: elements::FuncBody) -> Self {
279        self.func.code = body;
280        self
281    }
282
283    pub fn build(self) -> F::Result {
284        self.callback.invoke(self.func)
285    }
286}
287
288impl<F> Invoke<elements::FunctionType> for FunctionBuilder<F> where F: Invoke<FunctionDefinition> {
289	type Result = Self;
290
291	fn invoke(self, signature: elements::FunctionType) -> Self {
292		self.with_signature(Signature::Inline(signature))
293    }    
294}
295
296impl<F> Invoke<u32> for FunctionBuilder<F> where F: Invoke<FunctionDefinition> {
297	type Result = Self;
298
299	fn invoke(self, type_ref: u32) -> Self {
300		self.with_signature(Signature::TypeReference(type_ref))
301    }    
302}
303
304impl<F> Invoke<elements::FuncBody> for FunctionBuilder<F> where F: Invoke<FunctionDefinition> {
305    type Result = Self;
306
307    fn invoke(self, body: elements::FuncBody) -> Self::Result {
308        self.with_body(body)
309    }
310}
311
312/// New builder of signature list
313pub fn signatures() -> SignaturesBuilder {
314    SignaturesBuilder::new()
315}
316
317/// New signature builder
318pub fn signature() -> SignatureBuilder {
319    SignatureBuilder::new()
320}
321
322/// New builder of function (signature & body)
323pub fn function() -> FunctionBuilder {
324    FunctionBuilder::new()
325}
326
327#[cfg(test)]
328mod tests {
329
330    use super::{signatures, function};
331    use elements;
332
333    #[test]
334    fn example() {
335        let result = signatures()
336            .type_ref().val(1).build()
337            .build();
338
339        assert_eq!(result.entries().len(), 1);
340
341        let result = signatures()
342            .signature()
343                .param().i32()
344                .param().i32()
345                .return_type().i64()
346                .build()
347            .bind();      
348
349        assert_eq!(result.len(), 1);
350    }
351
352    #[test]
353    fn func_example() {
354        let func = function()
355            .signature()
356                .param().i32()
357                .return_type().i32()
358                .build()
359            .body()
360                .with_opcodes(elements::Opcodes::empty())
361                .build()
362            .build();
363
364        assert_eq!(func.code.locals().len(), 0);
365        assert_eq!(func.code.code().elements().len(), 1);
366    }
367}