1use std::ops::{Range, RangeFrom};
2
3use module::*;
4use types::*;
5use ops;
6use ops::Op;
7pub struct ModuleBuilder(Module);
8
9macro_rules! gen_add {
10 ($name: tt ($param: tt, $ty: ty) -> $ret: tt, $field: tt) => {
11 pub fn $name(&mut self, ty: $ty) -> $ret {
12
13 match &mut (self.0).$field {
14 &mut Some(ref mut v) => {
15 v.push(ty);
16 $ret::new((v.len() - 1) as u32)
17 },
18 none => {
19 *none = Some(vec![ty]);
20 $ret::new(0)
21 },
22 }
23 }
24 };
25
26 (prv, $name: tt ($param: tt, $ty: ty) -> $ret: tt, $field: tt) => {
27 fn $name(&mut self, ty: $ty) -> $ret {
28
29 match &mut (self.0).$field {
30 &mut Some(ref mut v) => {
31 v.push(ty);
32 $ret::new((v.len() - 1) as u32)
33 },
34 none => {
35 *none = Some(vec![ty]);
36 $ret::new(0)
37 },
38 }
39 }
40 };
41}
42
43impl ModuleBuilder {
44 pub fn new() -> Self {
45 ModuleBuilder(Module {
46 unknown: None,
47 types: None,
48 imports: None,
49 functions: None,
50 tables: None,
51 memories: None,
52 globals: None,
53 exports: None,
54 start: None,
55 elements: None,
56 codes: None,
57 data: None,
58 })
59 }
60
61 pub fn function_index_of(&self, i: ImportIndex) -> Result<FunctionSpaceIndex, ImportIndex> {
62 self.0.function_index_of(i)
63 }
64
65 fn nimports(&self) -> u32 {
66 self.0
67 .imports
68 .iter()
69 .flat_map(|i| i.iter())
70 .filter(|i| i.kind.is_function())
71 .count() as u32
72 }
73
74 fn resolve_functions(&mut self) {
75 let nimports = self.nimports();
76 for f in self.0.codes.iter_mut().flat_map(|f| f.iter_mut()) {
78 f.resolve_functions(nimports)
79 }
80 for e in self.0.elements.iter_mut().flat_map(|e| e.iter_mut()) {
82 for index in e.elems.iter_mut() {
83 use InnerFunctionSpaceIndex::*;
84 match index.0 {
85 Function(ref mut f) => {
86 f.0 += nimports;
87 }
88 _ => (),
89 }
90 }
91 }
92 }
93
94 pub fn build(mut self) -> Module {
95 self.resolve_functions();
96 let nimports = self.nimports();
97 self.0.start.as_mut().map(|i| i.0 += nimports);
98 self.0
99 }
100
101
102 gen_add!(add_type(ty, FuncType) -> TypeIndex,
103 types);
104 gen_add!(add_import(import, ImportEntry) -> ImportIndex,
105 imports);
106 gen_add!(prv, add_function(func, Function) -> FunctionIndex,
107 functions);
108 gen_add!(add_table(table, TableType) -> TableIndex,
109 tables);
110 gen_add!(add_memory(memory, MemoryType) -> MemoryIndex,
111 memories);
112 gen_add!(add_global(global, GlobalVariable) -> GlobalIndex,
113 globals);
114 gen_add!(add_export(export, ExportEntry) -> ExportIndex,
115 exports);
116 pub fn start(&mut self, index: FunctionIndex) {
117 self.0.start = Some(index);
118 }
119 gen_add!(add_element(element, ElemSegment) -> ElementIndex,
120 elements);
121 gen_add!(prv, add_code(code, FunctionBody) -> CodeIndex,
122 codes);
123 gen_add!(add_data(data, DataSegment) -> DataIndex,
124 data);
125
126 pub fn new_function(&mut self, (t, body): (FuncType, FunctionBody)) -> FunctionIndex {
127 let tidx = self.add_type(t);
128 let fidx = self.add_function(Function(tidx));
129 let cidx = self.add_code(body);
130 assert_eq!(*cidx, *fidx);
131 fidx
132 }
133
134 pub fn new_data(&mut self, idx: MemoryIndex, offset: Code, data: Vec<u8>) -> DataIndex {
135 let seg = DataSegment {
136 index: idx,
137 offset: InitExpr(offset),
138 data: data,
139 };
140 self.add_data(seg)
141 }
142
143 pub fn new_global(&mut self, ty: GlobalType, init: Code) -> GlobalIndex {
144 self.add_global(GlobalVariable {
145 ty: ty,
146 init: InitExpr(init),
147 })
148 }
149}
150
151pub trait NewTable<T> {
152 fn new_table(&mut self, element: ElemType, range: T) -> TableIndex;
153}
154
155impl NewTable<Range<u32>> for ModuleBuilder {
156 fn new_table(&mut self, element: ElemType, range: Range<u32>) -> TableIndex {
157 let table = TableType {
158 element: element,
159 limits: ResizableLimits::new(range.start).max(range.end),
160 };
161 self.add_table(table)
162 }
163}
164
165impl NewTable<RangeFrom<u32>> for ModuleBuilder {
166 fn new_table(&mut self, element: ElemType, range: RangeFrom<u32>) -> TableIndex {
167 let table = TableType {
168 element: element,
169 limits: ResizableLimits::new(range.start),
170 };
171 self.add_table(table)
172 }
173}
174
175pub trait NewMemory<T> {
176 fn new_memory(&mut self, range: T) -> MemoryIndex;
177}
178
179impl NewMemory<Range<u32>> for ModuleBuilder {
180 fn new_memory(&mut self, range: Range<u32>) -> MemoryIndex {
181 let memory = MemoryType { limits: ResizableLimits::new(range.start).max(range.end) };
182 self.add_memory(memory)
183 }
184}
185
186impl NewMemory<RangeFrom<u32>> for ModuleBuilder {
187 fn new_memory(&mut self, range: RangeFrom<u32>) -> MemoryIndex {
188 let memory = MemoryType { limits: ResizableLimits::new(range.start) };
189 self.add_memory(memory)
190 }
191}
192
193pub trait Export<T> {
194 fn export<S: Into<String>>(&mut self, name: S, index: T) -> ExportIndex;
195}
196
197
198macro_rules! gen_export {
199 ($name: ty, $variant: tt) => {
200 impl Export<$name> for ModuleBuilder {
201 fn export<S: Into<String>>(&mut self, name: S, index: $name) -> ExportIndex {
202 let entry = ExportEntry {
203 field: name.into(),
204 kind: ExportKind::$variant(index),
205 };
206 self.add_export(entry)
207 }
208 }
209 }
210}
211
212gen_export!(FunctionIndex, Function);
213gen_export!(TableIndex, Table);
214gen_export!(MemoryIndex, Memory);
215gen_export!(GlobalIndex, Global);
216
217
218pub trait Import<Ty> {
219 fn import<S, T>(&mut self, module: S, name: T, index: Ty) -> ImportIndex
220 where S: Into<String>,
221 T: Into<String>;
222}
223
224macro_rules! gen_import {
225 ($name: ty, $variant: tt) => {
226 impl Import<$name> for ModuleBuilder {
227 fn import<S, T>(&mut self, module: S, name: T, index: $name) -> ImportIndex
228 where S: Into<String>,
229 T: Into<String>
230 {
231 let entry = ImportEntry {
232 module: module.into(),
233 field: name.into(),
234 kind: ImportKind::$variant(index),
235 };
236 self.add_import(entry)
237 }
238 }
239 }
240}
241
242gen_import!(TypeIndex, Function);
243gen_import!(TableType, Table);
244gen_import!(MemoryType, Memory);
245gen_import!(GlobalType, Global);
246
247
248pub trait NewFunction<T> {
249 fn new_function(&mut self, t: T, body: FunctionBody) -> FunctionIndex;
250}
251
252impl NewFunction<TypeIndex> for ModuleBuilder {
253 fn new_function(&mut self, t: TypeIndex, body: FunctionBody) -> FunctionIndex {
254 let fidx = self.add_function(Function(t));
255 let cidx = self.add_code(body);
256 assert_eq!(*cidx, *fidx);
257 fidx
258 }
259}
260
261impl NewFunction<FuncType> for ModuleBuilder {
262 fn new_function(&mut self, t: FuncType, body: FunctionBody) -> FunctionIndex {
263 self.new_function((t, body))
264 }
265}
266
267
268
269pub struct CodeBuilder {
270 code: Vec<Op>,
271}
272
273macro_rules! gen_builder {
274 ($variant: path, $fname: ident) => {
275 pub fn $fname(mut self) -> Self {
276 self.code.push($variant);
277 self
278 }
279 };
280 ($variant: tt {$($arg: ident : $argty: ty, )* }, $fname: ident) => {
281 pub fn $fname(mut self, $($arg: $argty, )*) -> Self {
282 self.code.push($variant {
283 $($arg : $arg, )*
284 });
285 self
286 }
287 };
288
289 ($variant: tt { $arg: ident : $argty: ty $(, $args: ident : $argtys: ty)* }, $fname: ident) => {
290 gen_builder!($variant {$arg: $argty $(, $args : $argtys)*, }, $fname);
291 };
292
293 ($variant: tt [$($arg: ident : $argty: ty, )*], $fname: ident) => {
294 pub fn $fname(mut self, $($arg: $argty, )*) -> Self {
295 self.code.push($variant($($arg, )*));
296 self
297 }
298 };
299
300 ($variant: tt [ $arg: ident : $argty: ty $(, $args: ident : $argtys: ty)*], $fname: ident) => {
301 gen_builder!($variant [$arg: $argty $(, $args : $argtys)*, ], $fname);
302 };
303}
304
305macro_rules! gen_memory_builder {
306 ($variant: tt, $fname: ident, $align: expr) => {
307 pub fn $fname(mut self, offset: u32) -> Self {
308 let imm = ops::MemoryImmediate{
309 flags: $align - 3,
310 offset: offset
311 };
312 self.code.push($variant{imm: imm});
313 self
314 }
315 };
316
317}
318use Op::*;
319
320impl CodeBuilder {
321 pub fn new() -> Self {
322 CodeBuilder { code: Vec::new() }
323 }
324
325 pub fn build(self) -> Code {
326 Code(self.code)
327 }
328
329 gen_builder!(Unreachable, unreachable);
330 gen_builder!(Nop, nop);
331 gen_builder!(Block { sig: BlockType }, block);
332 gen_builder!(Loop { sig: BlockType }, loop_);
333 gen_builder!(If { sig: BlockType }, if_);
334 gen_builder!(Else, else_);
335 gen_builder!(End, end);
336 gen_builder!(Br { depth: u32 }, br);
337 gen_builder!(BrIf { depth: u32 }, br_if);
338 pub fn br_table(mut self, table: Vec<u32>, default: u32) -> Self {
339 self.code
340 .push(BrTable(ops::BrTarget {
341 table: table,
342 default_target: default,
343 }));
344 self
345 }
346 gen_builder!(Return, return_);
347
348 gen_builder!(Call { index: FunctionSpaceIndex }, call);
349 gen_builder!(CallIndirect {
350 index: TypeIndex,
351 reserved: bool,
352 },
353 call_indirect);
354
355 gen_builder!(Drop, drop);
356 gen_builder!(Select, select);
357
358 gen_builder!(GetLocal[idx: LocalIndex], get_local);
359 gen_builder!(SetLocal[idx: LocalIndex], set_local);
360 gen_builder!(TeeLocal[idx: LocalIndex], tee_local);
361 gen_builder!(GetGlobal[idx: GlobalIndex], get_global);
362 gen_builder!(SetGlobal[idx: GlobalIndex], set_global);
363
364 gen_memory_builder!(I32Load, i32_load, 5);
366 gen_memory_builder!(I64Load, i64_load, 6);
367 gen_memory_builder!(F32Load, f32_load, 5);
368 gen_memory_builder!(F64Load, f64_load, 6);
369 gen_memory_builder!(I32Load8S, i32_load8_s, 3);
370 gen_memory_builder!(I32Load8U, i32_load8_u, 3);
371 gen_memory_builder!(I32Load16S, i32_load16_s, 4);
372 gen_memory_builder!(I32Load16U, i32_load16_u, 4);
373 gen_memory_builder!(I64Load8S, i64_load8_s, 3);
374 gen_memory_builder!(I64Load8U, i64_load8_u, 3);
375 gen_memory_builder!(I64Load16S, i64_load16_s, 4);
376 gen_memory_builder!(I64Load16U, i64_load16_u, 4);
377 gen_memory_builder!(I64load32S, i64_load32_s, 5);
378 gen_memory_builder!(I64load32U, i64_load32_u, 5);
379 gen_memory_builder!(I32Store, i32_store, 5);
380 gen_memory_builder!(I64Store, i64_store, 6);
381 gen_memory_builder!(F32Store, f32_store, 5);
382 gen_memory_builder!(F64Store, f64_store, 6);
383 gen_memory_builder!(I32Store8, i32_store8, 3);
384 gen_memory_builder!(I32Store16, i32_store16, 4);
385 gen_memory_builder!(I64Store8, i64_store8, 3);
386 gen_memory_builder!(I64Store16, i64_store16, 4);
387 gen_memory_builder!(I64Store32, i64_store32, 5);
388 gen_builder!(CurrentMemory { reserved: bool }, current_memory);
389 gen_builder!(GrowMemory { reserved: bool }, grow_memory);
390
391
392 pub fn constant<C>(mut self, c: C) -> Self
393 where Op: From<C>
394 {
395 self.code.push(Op::from(c));
396 self
397 }
398
399 gen_builder!(I32Eqz, i32_eqz);
400 gen_builder!(I32Eq, i32_eq);
401 gen_builder!(I32NE, i32_ne);
402 gen_builder!(I32LtS, i32_lt_s);
403 gen_builder!(I32LtU, i32_lt_u);
404 gen_builder!(I32GtS, i32_gt_s);
405 gen_builder!(I32GtU, i32_gt_u);
406 gen_builder!(I32LeS, i32_le_s);
407 gen_builder!(I32LeU, i32_le_u);
408 gen_builder!(I32GeS, i32_ge_s);
409 gen_builder!(I32GeU, i32_ge_u);
410 gen_builder!(I64Eqz, i64_eqz);
411 gen_builder!(I64Eq, i64_eq);
412 gen_builder!(I64Ne, i64_ne);
413 gen_builder!(I64LtS, i64_lt_s);
414 gen_builder!(I64LtU, i64_lt_u);
415 gen_builder!(I64GtS, i64_gt_s);
416 gen_builder!(I64GtU, i64_gt_u);
417 gen_builder!(I64LeS, i64_le_s);
418 gen_builder!(I64LeU, i64_le_u);
419 gen_builder!(I64GeS, i64_ge_s);
420 gen_builder!(I64GeU, i64_ge_u);
421 gen_builder!(F32Eq, f32_eq);
422 gen_builder!(F32Ne, f32_ne);
423 gen_builder!(F32Lt, f32_lt);
424 gen_builder!(F32Gt, f32_gt);
425 gen_builder!(F32Le, f32_le);
426 gen_builder!(F32Ge, f32_ge);
427 gen_builder!(F64Eq, f64_eq);
428 gen_builder!(F64Ne, f64_ne);
429 gen_builder!(F64Lt, f64_lt);
430 gen_builder!(F64Gt, f64_gt);
431 gen_builder!(F64Le, f64_le);
432 gen_builder!(F64Ge, f64_ge);
433
434 gen_builder!(I32Clz, i32_clz);
435 gen_builder!(I32Ctz, i32_ctz);
436 gen_builder!(I32Popcnt, i32_popcnt);
437 gen_builder!(I32Add, i32_add);
438 gen_builder!(I32Sub, i32_sub);
439 gen_builder!(I32Mul, i32_mul);
440 gen_builder!(I32DivS, i32_div_s);
441 gen_builder!(I32DivU, i32_div_u);
442 gen_builder!(I32RemS, i32_rem_s);
443 gen_builder!(I32RemU, i32_rem_u);
444 gen_builder!(I32And, i32_and);
445 gen_builder!(I32Or, i32_or);
446 gen_builder!(I32Xor, i32_xor);
447 gen_builder!(I32Shl, i32_shl);
448 gen_builder!(I32ShrS, i32_shr_s);
449 gen_builder!(I32ShrU, i32_shr_u);
450 gen_builder!(I32Rotl, i32_rotl);
451 gen_builder!(I32Rotr, i32_rotr);
452 gen_builder!(I64Clz, i64_clz);
453 gen_builder!(I64Ctz, i64_ctz);
454 gen_builder!(I64Popcnt, i64_popcnt);
455 gen_builder!(I64Add, i64_add);
456 gen_builder!(I64Sub, i64_sub);
457 gen_builder!(I64Mul, i64_mul);
458 gen_builder!(I64DivS, i64_div_s);
459 gen_builder!(I64DivU, i64_div_u);
460 gen_builder!(I64RemS, i64_rem_s);
461 gen_builder!(I64RemU, i64_rem_u);
462 gen_builder!(I64And, i64_and);
463 gen_builder!(I64Or, i64_or);
464 gen_builder!(I64Xor, i64_xor);
465 gen_builder!(I64Shl, i64_shl);
466 gen_builder!(I64ShrS, i64_shr_s);
467 gen_builder!(I64ShrU, i64_shr_u);
468 gen_builder!(I64Rotl, i64_rotl);
469 gen_builder!(I64Rotr, i64_rotr);
470 gen_builder!(F32Abs, f32_abs);
471 gen_builder!(F32Neg, f32_neg);
472 gen_builder!(F32Ceil, f32_ceil);
473 gen_builder!(F32Floor, f32_floor);
474 gen_builder!(F32Trunc, f32_trunc);
475 gen_builder!(F32Nearest, f32_nearest);
476 gen_builder!(F32Sqrt, f32_sqrt);
477 gen_builder!(F32Add, f32_add);
478 gen_builder!(F32Sub, f32_sub);
479 gen_builder!(F32Mul, f32_mul);
480 gen_builder!(F32Div, f32_div);
481 gen_builder!(F32Min, f32_min);
482 gen_builder!(F32Max, f32_max);
483 gen_builder!(F32Copysign, f32_copysign);
484 gen_builder!(F64Abs, f64_abs);
485 gen_builder!(F64Neg, f64_neg);
486 gen_builder!(F64Ceil, f64_ceil);
487 gen_builder!(F64Floor, f64_floor);
488 gen_builder!(F64Trunc, f64_trunc);
489 gen_builder!(F64Nearest, f64_nearest);
490 gen_builder!(F64Sqrt, f64_sqrt);
491 gen_builder!(F64Add, f64_add);
492 gen_builder!(F64Sub, f64_sub);
493 gen_builder!(F64Mul, f64_mul);
494 gen_builder!(F64Div, f64_div);
495 gen_builder!(F64Min, f64_min);
496 gen_builder!(F64Max, f64_max);
497 gen_builder!(F64Copysign, f64_copysign);
498
499 gen_builder!(I32wrapI64, i32_wrap_i64);
500 gen_builder!(I32TruncSF32, i32_trunc_s_f32);
501 gen_builder!(I32TruncUF32, i32_trunc_u_f32);
502 gen_builder!(I32TruncSF64, i32_trunc_s_f64);
503 gen_builder!(I32TruncUF64, i32_trunc_u_f64);
504 gen_builder!(I64ExtendSI32, i64_extend_s_i32);
505 gen_builder!(I64ExtendUI32, i64_extend_u_i32);
506 gen_builder!(I64TruncSF32, i64_trunc_s_f32);
507 gen_builder!(I64TruncUF32, i64_trunc_u_f32);
508 gen_builder!(I64TruncSF64, i64_trunc_s_f64);
509 gen_builder!(I64TruncUF64, i64_trunc_u_f64);
510 gen_builder!(F32ConvertSI32, f32_convert_s_i32);
511 gen_builder!(F32ConvertUI32, f32_convert_u_i32);
512 gen_builder!(F32ConvertSI64, f32_convert_s_i64);
513 gen_builder!(F32ConvertUI64, f32_convert_u_i64);
514 gen_builder!(F32DemoteF64, f32_demote_f64);
515 gen_builder!(F64ConvertSI32, f64_convert_s_i32);
516 gen_builder!(F64ConvertUI32, f64_convert_u_i32);
517 gen_builder!(F64ConvertSI64, f64_convert_s_i64);
518 gen_builder!(F64ConvertUI64, f64_convert_u_i64);
519 gen_builder!(F64PromoteF32, f64_promote_f32);
520
521 gen_builder!(I32ReinterpretF32, i32_reinterpret_f32);
522 gen_builder!(I64ReinterpretF64, i64_reinterpret_f64);
523 gen_builder!(F32ReinterpretI32, f32_reinterpret_i32);
524 gen_builder!(F64ReinterpretI64, f64_reinterpret_i64);
525}
526
527pub struct FunctionBuilder {
528 ty: FuncType,
529 args: Vec<LocalIndex>,
530 locals: Vec<ValueType>,
531 cb: CodeBuilder,
532}
533
534
535impl FunctionBuilder {
536 pub fn new(ty: FuncType) -> Self {
537 let args = (0..ty.params.len())
538 .map(|i| LocalIndex::new(i as u32))
539 .collect();
540 let fb = FunctionBuilder {
541 ty: ty,
542 args: args,
543 locals: Vec::new(),
544 cb: CodeBuilder::new(),
545 };
546 fb
547 }
548
549 pub fn build(self) -> (FuncType, FunctionBody) {
550 let locals = self.locals
552 .into_iter()
553 .map(|l| LocalEntry { count: 1, ty: l })
554 .collect();
555 let body = FunctionBody {
556 locals: locals,
557 code: self.cb.build(),
558 };
559 (self.ty, body)
560 }
561
562 pub fn new_local(&mut self, ty: ValueType) -> LocalIndex {
563 self.locals.push(ty);
564 LocalIndex::new((self.ty.params.len() + self.locals.len() - 1) as u32)
565 }
566
567 pub fn new_locals(&mut self, tys: Vec<ValueType>) -> Vec<LocalIndex> {
568 tys.into_iter()
569 .map(|ty| {
570 self.locals.push(ty);
571 LocalIndex::new((self.ty.params.len() + self.locals.len() - 1) as u32)
572 })
573 .collect()
574 }
575
576 pub fn code<F: FnOnce(CodeBuilder, &[LocalIndex]) -> CodeBuilder>(mut self, f: F) -> Self {
577 self.cb = f(self.cb, &self.args);
578 self
579 }
580}
581
582#[macro_export]
583macro_rules! ty {
584 (i32) => (ValueType::I32);
585 (i64) => (ValueType::I64);
586 (f32) => (ValueType::F32);
587 (f64) => (ValueType::F64);
588}
589
590
591#[macro_export]
592macro_rules! ty_vec {
593 ($($t: tt, )*) => {
594 vec!($(ty!($t), )*)
595 };
596
597 ($t: tt $(, $ts: tt)*) => {
598 vec!(ty!($t) $(, ty!($ts))*)
599 };
600}
601
602#[macro_export]
603macro_rules! funtype {
604 (($($params: tt)*) -> $ret: tt) => {
605 FuncType {
606 params: ty_vec!($($params)*),
607 ret: Some(ty!($ret))
608 }
609 };
610 (($($params: tt)*)) => {
611 FuncType {
612 params: ty_vec!($($params)*),
613 ret: None,
614 }
615 };
616}