sophon_wasm/builder/
code.rs1use 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 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!(); }
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
312pub fn signatures() -> SignaturesBuilder {
314 SignaturesBuilder::new()
315}
316
317pub fn signature() -> SignatureBuilder {
319 SignatureBuilder::new()
320}
321
322pub 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}