parity_wasm/builder/
code.rs1use super::{
2 invoke::{Identity, Invoke},
3 misc::{ValueTypeBuilder, ValueTypesBuilder},
4};
5use crate::elements;
6use alloc::vec::Vec;
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 Default for SignatureBuilder {
28 fn default() -> Self {
29 Self::new()
30 }
31}
32impl<F> SignatureBuilder<F>
33where
34 F: Invoke<elements::FunctionType>,
35{
36 pub fn with_callback(callback: F) -> Self {
38 SignatureBuilder { callback, signature: elements::FunctionType::default() }
39 }
40
41 pub fn with_param(mut self, value_type: elements::ValueType) -> Self {
43 self.signature.params_mut().push(value_type);
44 self
45 }
46
47 pub fn with_params<I>(mut self, value_types: I) -> Self
49 where
50 I: IntoIterator<Item = elements::ValueType>,
51 {
52 self.signature.params_mut().extend(value_types);
53 self
54 }
55
56 pub fn param(self) -> ValueTypeBuilder<Self> {
58 ValueTypeBuilder::with_callback(self)
59 }
60
61 pub fn params(self) -> ValueTypesBuilder<Self> {
63 ValueTypesBuilder::with_callback(self)
64 }
65
66 pub fn with_result(mut self, value_type: elements::ValueType) -> Self {
68 self.signature.results_mut().push(value_type);
69 self
70 }
71
72 pub fn with_results<I>(mut self, value_types: I) -> Self
74 where
75 I: IntoIterator<Item = elements::ValueType>,
76 {
77 self.signature.results_mut().extend(value_types);
78 self
79 }
80
81 pub fn result(self) -> ValueTypeBuilder<Self> {
83 ValueTypeBuilder::with_callback(self)
84 }
85
86 pub fn results(self) -> ValueTypeBuilder<Self> {
88 ValueTypeBuilder::with_callback(self)
89 }
90
91 pub fn build(self) -> F::Result {
93 self.callback.invoke(self.signature)
94 }
95
96 pub fn build_sig(self) -> Signature {
98 Signature::Inline(self.signature)
99 }
100}
101
102impl<F, I> Invoke<I> for SignatureBuilder<F>
103where
104 F: Invoke<elements::FunctionType>,
105 I: IntoIterator<Item = elements::ValueType>,
106{
107 type Result = Self;
108
109 fn invoke(self, args: I) -> Self {
110 self.with_params(args)
111 }
112}
113
114impl<F> Invoke<elements::ValueType> for SignatureBuilder<F>
115where
116 F: Invoke<elements::FunctionType>,
117{
118 type Result = Self;
119
120 fn invoke(self, arg: elements::ValueType) -> Self {
121 self.with_result(arg)
122 }
123}
124
125pub struct TypeRefBuilder<F = Identity> {
127 callback: F,
128 type_ref: u32,
129}
130
131impl<F> TypeRefBuilder<F>
132where
133 F: Invoke<u32>,
134{
135 pub fn with_callback(callback: F) -> Self {
137 TypeRefBuilder { callback, type_ref: 0 }
138 }
139
140 pub fn val(mut self, val: u32) -> Self {
142 self.type_ref = val;
143 self
144 }
145
146 pub fn build(self) -> F::Result {
148 self.callback.invoke(self.type_ref)
149 }
150}
151
152pub struct SignaturesBuilder<F = Identity> {
154 callback: F,
155 section: Vec<Signature>,
156}
157
158impl SignaturesBuilder {
159 pub fn new() -> Self {
161 SignaturesBuilder::with_callback(Identity)
162 }
163}
164
165impl Default for SignaturesBuilder {
166 fn default() -> Self {
167 Self::new()
168 }
169}
170
171impl<F> SignaturesBuilder<F> {
172 pub fn with_callback(callback: F) -> Self {
174 SignaturesBuilder { callback, section: Vec::new() }
175 }
176
177 pub fn with_signature(mut self, signature: Signature) -> Self {
179 self.section.push(signature);
180 self
181 }
182
183 pub fn type_ref(self) -> TypeRefBuilder<Self> {
185 TypeRefBuilder::with_callback(self)
186 }
187}
188
189impl<F> SignaturesBuilder<F>
190where
191 F: Invoke<SignatureBindings>,
192{
193 pub fn signature(self) -> SignatureBuilder<Self> {
195 SignatureBuilder::with_callback(self)
196 }
197}
198
199impl<F> Invoke<elements::FunctionType> for SignaturesBuilder<F> {
200 type Result = Self;
201
202 fn invoke(self, signature: elements::FunctionType) -> Self {
203 self.with_signature(Signature::Inline(signature))
204 }
205}
206
207impl<F> Invoke<u32> for SignaturesBuilder<F> {
208 type Result = Self;
209
210 fn invoke(self, type_ref: u32) -> Self {
211 self.with_signature(Signature::TypeReference(type_ref))
212 }
213}
214
215impl<F> SignaturesBuilder<F>
216where
217 F: Invoke<elements::FunctionSection>,
218{
219 pub fn build(self) -> F::Result {
221 let mut result = elements::FunctionSection::default();
222 for f in self.section.into_iter() {
223 if let Signature::TypeReference(type_ref) = f {
224 result.entries_mut().push(elements::Func::new(type_ref));
225 } else {
226 unreachable!(); }
228 }
229 self.callback.invoke(result)
230 }
231}
232
233pub type SignatureBindings = Vec<Signature>;
235
236impl<F> SignaturesBuilder<F>
237where
238 F: Invoke<SignatureBindings>,
239{
240 pub fn bind(self) -> F::Result {
242 self.callback.invoke(self.section)
243 }
244}
245
246pub struct FuncBodyBuilder<F = Identity> {
248 callback: F,
249 body: elements::FuncBody,
250}
251
252impl<F> FuncBodyBuilder<F> {
253 pub fn with_callback(callback: F) -> Self {
255 FuncBodyBuilder {
256 callback,
257 body: elements::FuncBody::new(Vec::new(), elements::Instructions::empty()),
258 }
259 }
260}
261
262impl<F> FuncBodyBuilder<F>
263where
264 F: Invoke<elements::FuncBody>,
265{
266 pub fn with_func(mut self, func: elements::FuncBody) -> Self {
268 self.body = func;
269 self
270 }
271
272 pub fn with_locals<I>(mut self, locals: I) -> Self
274 where
275 I: IntoIterator<Item = elements::Local>,
276 {
277 self.body.locals_mut().extend(locals);
278 self
279 }
280
281 pub fn with_instructions(mut self, instructions: elements::Instructions) -> Self {
283 *self.body.code_mut() = instructions;
284 self
285 }
286
287 pub fn build(self) -> F::Result {
289 self.callback.invoke(self.body)
290 }
291}
292
293pub struct FunctionDefinition {
295 pub is_main: bool,
297 pub signature: Signature,
299 pub code: elements::FuncBody,
301}
302
303impl Default for FunctionDefinition {
304 fn default() -> Self {
305 FunctionDefinition {
306 is_main: false,
307 signature: Signature::TypeReference(0),
308 code: elements::FuncBody::empty(),
309 }
310 }
311}
312
313pub struct FunctionBuilder<F = Identity> {
315 callback: F,
316 func: FunctionDefinition,
317}
318
319impl FunctionBuilder {
320 pub fn new() -> Self {
322 FunctionBuilder::with_callback(Identity)
323 }
324}
325
326impl Default for FunctionBuilder {
327 fn default() -> Self {
328 Self::new()
329 }
330}
331
332impl<F> FunctionBuilder<F>
333where
334 F: Invoke<FunctionDefinition>,
335{
336 pub fn with_callback(callback: F) -> Self {
338 FunctionBuilder { callback, func: Default::default() }
339 }
340
341 pub fn main(mut self) -> Self {
343 self.func.is_main = true;
344 self
345 }
346
347 pub fn signature(self) -> SignatureBuilder<Self> {
349 SignatureBuilder::with_callback(self)
350 }
351
352 pub fn with_signature(mut self, signature: Signature) -> Self {
354 self.func.signature = signature;
355 self
356 }
357
358 pub fn body(self) -> FuncBodyBuilder<Self> {
360 FuncBodyBuilder::with_callback(self)
361 }
362
363 pub fn with_body(mut self, body: elements::FuncBody) -> Self {
365 self.func.code = body;
366 self
367 }
368
369 pub fn build(self) -> F::Result {
371 self.callback.invoke(self.func)
372 }
373}
374
375impl<F> Invoke<elements::FunctionType> for FunctionBuilder<F>
376where
377 F: Invoke<FunctionDefinition>,
378{
379 type Result = Self;
380
381 fn invoke(self, signature: elements::FunctionType) -> Self {
382 self.with_signature(Signature::Inline(signature))
383 }
384}
385
386impl<F> Invoke<u32> for FunctionBuilder<F>
387where
388 F: Invoke<FunctionDefinition>,
389{
390 type Result = Self;
391
392 fn invoke(self, type_ref: u32) -> Self {
393 self.with_signature(Signature::TypeReference(type_ref))
394 }
395}
396
397impl<F> Invoke<elements::FuncBody> for FunctionBuilder<F>
398where
399 F: Invoke<FunctionDefinition>,
400{
401 type Result = Self;
402
403 fn invoke(self, body: elements::FuncBody) -> Self::Result {
404 self.with_body(body)
405 }
406}
407
408pub fn signatures() -> SignaturesBuilder {
410 SignaturesBuilder::new()
411}
412
413pub fn signature() -> SignatureBuilder {
415 SignatureBuilder::new()
416}
417
418pub fn function() -> FunctionBuilder {
420 FunctionBuilder::new()
421}
422
423#[cfg(test)]
424mod tests {
425
426 use super::{function, signatures};
427 use crate::elements;
428
429 #[test]
430 fn example() {
431 let result = signatures().type_ref().val(1).build().build();
432
433 assert_eq!(result.entries().len(), 1);
434
435 let result = signatures()
436 .signature()
437 .param()
438 .i32()
439 .param()
440 .i32()
441 .result()
442 .i64()
443 .build()
444 .bind();
445
446 assert_eq!(result.len(), 1);
447 }
448
449 #[test]
450 fn func_example() {
451 let func = function()
452 .signature()
453 .param()
454 .i32()
455 .result()
456 .i32()
457 .build()
458 .body()
459 .with_instructions(elements::Instructions::empty())
460 .build()
461 .build();
462
463 assert_eq!(func.code.locals().len(), 0);
464 assert_eq!(func.code.code().elements().len(), 1);
465 }
466
467 #[test]
468 fn func_example_multi_result() {
469 let func = function()
470 .signature()
471 .param()
472 .i32()
473 .result()
474 .i32()
475 .result()
476 .i32()
477 .build()
478 .body()
479 .with_instructions(elements::Instructions::empty())
480 .build()
481 .build();
482
483 assert_eq!(func.code.locals().len(), 0);
484 assert_eq!(func.code.code().elements().len(), 1);
485 }
486}