tetsy_wasm/builder/
code.rs1use alloc::vec::Vec;
2use crate::elements;
3use super::{
4 invoke::{Invoke, Identity},
5 misc::{ValueTypeBuilder, ValueTypesBuilder},
6};
7
8pub enum Signature {
10 TypeReference(u32),
11 Inline(elements::FunctionType),
12}
13
14pub struct SignatureBuilder<F=Identity> {
16 callback: F,
17 signature: elements::FunctionType,
18}
19
20impl SignatureBuilder {
21 pub fn new() -> Self {
23 SignatureBuilder::with_callback(Identity)
24 }
25}
26
27impl<F> SignatureBuilder<F> where F: Invoke<elements::FunctionType> {
28 pub fn with_callback(callback: F) -> Self {
30 SignatureBuilder {
31 callback: callback,
32 signature: elements::FunctionType::default(),
33 }
34 }
35
36 pub fn with_param(mut self, value_type: elements::ValueType) -> Self {
38 self.signature.params_mut().push(value_type);
39 self
40 }
41
42 pub fn with_params(mut self, value_types: Vec<elements::ValueType>) -> Self {
44 self.signature.params_mut().extend(value_types);
45 self
46 }
47
48 pub fn param(self) -> ValueTypeBuilder<Self> {
50 ValueTypeBuilder::with_callback(self)
51 }
52
53 pub fn params(self) -> ValueTypesBuilder<Self> {
55 ValueTypesBuilder::with_callback(self)
56 }
57
58 pub fn with_result(mut self, value_type: elements::ValueType) -> Self {
60 self.signature.results_mut().push(value_type);
61 self
62 }
63
64 pub fn with_results(mut self, value_types: Vec<elements::ValueType>) -> Self {
66 self.signature.results_mut().extend(value_types);
67 self
68 }
69
70 pub fn result(self) -> ValueTypeBuilder<Self> {
72 ValueTypeBuilder::with_callback(self)
73 }
74
75 pub fn results(self) -> ValueTypeBuilder<Self> {
77 ValueTypeBuilder::with_callback(self)
78 }
79
80 pub fn build(self) -> F::Result {
82 self.callback.invoke(self.signature)
83 }
84
85 pub fn build_sig(self) -> Signature {
87 Signature::Inline(self.signature)
88 }
89}
90
91impl<F> Invoke<Vec<elements::ValueType>> for SignatureBuilder<F>
92 where F: Invoke<elements::FunctionType>
93{
94 type Result = Self;
95
96 fn invoke(self, args: Vec<elements::ValueType>) -> Self {
97 self.with_params(args)
98 }
99}
100
101impl<F> Invoke<elements::ValueType> for SignatureBuilder<F>
102 where F: Invoke<elements::FunctionType>
103{
104 type Result = Self;
105
106 fn invoke(self, arg: elements::ValueType) -> Self {
107 self.with_result(arg)
108 }
109}
110
111pub struct TypeRefBuilder<F=Identity> {
113 callback: F,
114 type_ref: u32,
115}
116
117impl<F> TypeRefBuilder<F> where F: Invoke<u32> {
118 pub fn with_callback(callback: F) -> Self {
120 TypeRefBuilder {
121 callback: callback,
122 type_ref: 0
123 }
124 }
125
126 pub fn val(mut self, val: u32) -> Self {
128 self.type_ref = val;
129 self
130 }
131
132 pub fn build(self) -> F::Result { self.callback.invoke(self.type_ref) }
134}
135
136pub struct SignaturesBuilder<F=Identity> {
138 callback: F,
139 section: Vec<Signature>,
140}
141
142impl SignaturesBuilder {
143 pub fn new() -> Self {
145 SignaturesBuilder::with_callback(Identity)
146 }
147}
148
149impl<F> SignaturesBuilder<F> {
150 pub fn with_callback(callback: F) -> Self {
152 SignaturesBuilder {
153 callback: callback,
154 section: Vec::new(),
155 }
156 }
157
158 pub fn with_signature(mut self, signature: Signature) -> Self {
160 self.section.push(signature);
161 self
162 }
163
164 pub fn type_ref(self) -> TypeRefBuilder<Self> {
166 TypeRefBuilder::with_callback(self)
167 }
168}
169
170impl<F> SignaturesBuilder<F> where F: Invoke<SignatureBindings> {
171 pub fn signature(self) -> SignatureBuilder<Self> {
173 SignatureBuilder::with_callback(self)
174 }
175}
176
177impl<F> Invoke<elements::FunctionType> for SignaturesBuilder<F> {
178 type Result = Self;
179
180 fn invoke(self, signature: elements::FunctionType) -> Self {
181 self.with_signature(Signature::Inline(signature))
182 }
183}
184
185impl<F> Invoke<u32> for SignaturesBuilder<F> {
186 type Result = Self;
187
188 fn invoke(self, type_ref: u32) -> Self {
189 self.with_signature(Signature::TypeReference(type_ref))
190 }
191}
192
193impl<F> SignaturesBuilder<F> where F: Invoke<elements::FunctionSection> {
194
195 pub fn build(self) -> F::Result {
197 let mut result = elements::FunctionSection::default();
198 for f in self.section.into_iter() {
199 if let Signature::TypeReference(type_ref) = f {
200 result.entries_mut().push(elements::Func::new(type_ref));
201 } else {
202 unreachable!(); }
204 }
205 self.callback.invoke(result)
206 }
207}
208
209pub type SignatureBindings = Vec<Signature>;
211
212impl<F> SignaturesBuilder<F> where F: Invoke<SignatureBindings> {
213 pub fn bind(self) -> F::Result {
215 self.callback.invoke(self.section)
216 }
217}
218
219pub struct FuncBodyBuilder<F=Identity> {
221 callback: F,
222 body: elements::FuncBody,
223}
224
225impl<F> FuncBodyBuilder<F> {
226 pub fn with_callback(callback: F) -> Self {
228 FuncBodyBuilder {
229 callback: callback,
230 body: elements::FuncBody::new(Vec::new(), elements::Instructions::empty()),
231 }
232 }
233}
234
235impl<F> FuncBodyBuilder<F> where F: Invoke<elements::FuncBody> {
236 pub fn with_func(mut self, func: elements::FuncBody) -> Self {
238 self.body = func;
239 self
240 }
241
242 pub fn with_locals(mut self, locals: Vec<elements::Local>) -> Self {
244 self.body.locals_mut().extend(locals);
245 self
246 }
247
248 pub fn with_instructions(mut self, instructions: elements::Instructions) -> Self {
250 *self.body.code_mut() = instructions;
251 self
252 }
253
254 pub fn build(self) -> F::Result {
256 self.callback.invoke(self.body)
257 }
258}
259
260pub struct FunctionDefinition {
262 pub is_main: bool,
264 pub signature: Signature,
266 pub code: elements::FuncBody,
268}
269
270impl Default for FunctionDefinition {
271 fn default() -> Self {
272 FunctionDefinition {
273 is_main: false,
274 signature: Signature::TypeReference(0),
275 code: elements::FuncBody::empty(),
276 }
277 }
278}
279
280pub struct FunctionBuilder<F=Identity> {
282 callback: F,
283 func: FunctionDefinition,
284}
285
286impl FunctionBuilder {
287 pub fn new() -> Self {
289 FunctionBuilder::with_callback(Identity)
290 }
291}
292
293impl<F> FunctionBuilder<F> where F: Invoke<FunctionDefinition> {
294 pub fn with_callback(callback: F) -> Self {
296 FunctionBuilder {
297 callback: callback,
298 func: Default::default(),
299 }
300 }
301
302 pub fn main(mut self) -> Self {
304 self.func.is_main = true;
305 self
306 }
307
308 pub fn signature(self) -> SignatureBuilder<Self> {
310 SignatureBuilder::with_callback(self)
311 }
312
313 pub fn with_signature(mut self, signature: Signature) -> Self {
315 self.func.signature = signature;
316 self
317 }
318
319 pub fn body(self) -> FuncBodyBuilder<Self> {
321 FuncBodyBuilder::with_callback(self)
322 }
323
324 pub fn with_body(mut self, body: elements::FuncBody) -> Self {
326 self.func.code = body;
327 self
328 }
329
330 pub fn build(self) -> F::Result {
332 self.callback.invoke(self.func)
333 }
334}
335
336impl<F> Invoke<elements::FunctionType> for FunctionBuilder<F> where F: Invoke<FunctionDefinition> {
337 type Result = Self;
338
339 fn invoke(self, signature: elements::FunctionType) -> Self {
340 self.with_signature(Signature::Inline(signature))
341 }
342}
343
344impl<F> Invoke<u32> for FunctionBuilder<F> where F: Invoke<FunctionDefinition> {
345 type Result = Self;
346
347 fn invoke(self, type_ref: u32) -> Self {
348 self.with_signature(Signature::TypeReference(type_ref))
349 }
350}
351
352impl<F> Invoke<elements::FuncBody> for FunctionBuilder<F> where F: Invoke<FunctionDefinition> {
353 type Result = Self;
354
355 fn invoke(self, body: elements::FuncBody) -> Self::Result {
356 self.with_body(body)
357 }
358}
359
360pub fn signatures() -> SignaturesBuilder {
362 SignaturesBuilder::new()
363}
364
365pub fn signature() -> SignatureBuilder {
367 SignatureBuilder::new()
368}
369
370pub fn function() -> FunctionBuilder {
372 FunctionBuilder::new()
373}
374
375#[cfg(test)]
376mod tests {
377
378 use super::{signatures, function};
379 use crate::elements;
380
381 #[test]
382 fn example() {
383 let result = signatures()
384 .type_ref().val(1).build()
385 .build();
386
387 assert_eq!(result.entries().len(), 1);
388
389 let result = signatures()
390 .signature()
391 .param().i32()
392 .param().i32()
393 .result().i64()
394 .build()
395 .bind();
396
397 assert_eq!(result.len(), 1);
398 }
399
400 #[test]
401 fn func_example() {
402 let func = function()
403 .signature()
404 .param().i32()
405 .result().i32()
406 .build()
407 .body()
408 .with_instructions(elements::Instructions::empty())
409 .build()
410 .build();
411
412 assert_eq!(func.code.locals().len(), 0);
413 assert_eq!(func.code.code().elements().len(), 1);
414 }
415
416 #[test]
417 fn func_example_multi_result() {
418 let func = function()
419 .signature()
420 .param().i32()
421 .result().i32()
422 .result().i32()
423 .build()
424 .body()
425 .with_instructions(elements::Instructions::empty())
426 .build()
427 .build();
428
429 assert_eq!(func.code.locals().len(), 0);
430 assert_eq!(func.code.code().elements().len(), 1);
431 }
432}