1use super::{
2 inst_builder::{InstBuilder, InstBuilderBase, InstBuilderExt},
3 IRContext, IRRegistry,
4};
5use crate::{
6 block::{BasicBlock, BlockId, Terminator},
7 contract::EventId,
8 instructions::{CallTarget, ContextVariable, Instruction, StorageKey},
9 types::Type,
10 values::{Constant, SourceLocation, Value},
11 Result,
12};
13use num_bigint::{BigInt, BigUint};
14use std::collections::HashMap;
15
16pub struct BlockBuilder<'a> {
17 pub block_id: BlockId,
18 function_name: String,
19 instructions: Vec<Instruction>,
20 context: &'a mut IRContext,
21 registry: &'a mut IRRegistry,
22 is_sealed: bool,
23 current_source_location: Option<SourceLocation>,
24 instruction_locations: HashMap<usize, SourceLocation>,
25}
26
27impl<'a> BlockBuilder<'a> {
28 pub fn new(
29 block_id: BlockId,
30 function_name: String,
31 context: &'a mut IRContext,
32 registry: &'a mut IRRegistry,
33 ) -> Self {
34 Self {
35 block_id,
36 function_name,
37 instructions: Vec::new(),
38 context,
39 registry,
40 is_sealed: false,
41 current_source_location: None,
42 instruction_locations: HashMap::new(),
43 }
44 }
45
46 pub fn set_source_location(&mut self, location: SourceLocation) {
47 self.current_source_location = Some(location);
48 }
49
50 pub fn clear_source_location(&mut self) {
51 self.current_source_location = None;
52 }
53
54 fn record_instruction_location(&mut self) {
55 if let Some(ref location) = self.current_source_location {
56 let index = self.instructions.len();
57 self.instruction_locations.insert(index, location.clone());
58 }
59 }
60
61 fn push_instruction(&mut self, inst: Instruction) {
62 self.record_instruction_location();
63 self.instructions.push(inst);
64 }
65
66 pub fn block_id(&self) -> BlockId {
67 self.block_id
68 }
69
70 pub fn add(&mut self, left: Value, right: Value, ty: Type) -> Value {
71 let result = self.new_temp();
72 self.push_instruction(Instruction::Add {
73 result: result.clone(),
74 left,
75 right,
76 ty,
77 });
78 result
79 }
80
81 pub fn sub(&mut self, left: Value, right: Value, ty: Type) -> Value {
82 let result = self.new_temp();
83 self.push_instruction(Instruction::Sub {
84 result: result.clone(),
85 left,
86 right,
87 ty,
88 });
89 result
90 }
91
92 pub fn mul(&mut self, left: Value, right: Value, ty: Type) -> Value {
93 let result = self.new_temp();
94 self.push_instruction(Instruction::Mul {
95 result: result.clone(),
96 left,
97 right,
98 ty,
99 });
100 result
101 }
102
103 pub fn div(&mut self, left: Value, right: Value, ty: Type) -> Value {
104 let result = self.new_temp();
105 self.push_instruction(Instruction::Div {
106 result: result.clone(),
107 left,
108 right,
109 ty,
110 });
111 result
112 }
113
114 pub fn mod_(&mut self, left: Value, right: Value, ty: Type) -> Value {
115 let result = self.new_temp();
116 self.push_instruction(Instruction::Mod {
117 result: result.clone(),
118 left,
119 right,
120 ty,
121 });
122 result
123 }
124
125 pub fn pow(&mut self, base: Value, exp: Value) -> Value {
126 let result = self.new_temp();
127 self.push_instruction(Instruction::Pow {
128 result: result.clone(),
129 base,
130 exp,
131 });
132 result
133 }
134
135 pub fn checked_add(&mut self, left: Value, right: Value, ty: Type) -> Value {
136 let result = self.new_temp();
137 self.push_instruction(Instruction::CheckedAdd {
138 result: result.clone(),
139 left,
140 right,
141 ty,
142 });
143 result
144 }
145
146 pub fn checked_sub(&mut self, left: Value, right: Value, ty: Type) -> Value {
147 let result = self.new_temp();
148 self.push_instruction(Instruction::CheckedSub {
149 result: result.clone(),
150 left,
151 right,
152 ty,
153 });
154 result
155 }
156
157 pub fn checked_mul(&mut self, left: Value, right: Value, ty: Type) -> Value {
158 let result = self.new_temp();
159 self.push_instruction(Instruction::CheckedMul {
160 result: result.clone(),
161 left,
162 right,
163 ty,
164 });
165 result
166 }
167
168 pub fn and(&mut self, left: Value, right: Value) -> Value {
169 let result = self.new_temp();
170 self.push_instruction(Instruction::And {
171 result: result.clone(),
172 left,
173 right,
174 });
175 result
176 }
177
178 pub fn or(&mut self, left: Value, right: Value) -> Value {
179 let result = self.new_temp();
180 self.push_instruction(Instruction::Or {
181 result: result.clone(),
182 left,
183 right,
184 });
185 result
186 }
187
188 pub fn xor(&mut self, left: Value, right: Value) -> Value {
189 let result = self.new_temp();
190 self.push_instruction(Instruction::Xor {
191 result: result.clone(),
192 left,
193 right,
194 });
195 result
196 }
197
198 pub fn not(&mut self, operand: Value) -> Value {
199 let result = self.new_temp();
200 self.push_instruction(Instruction::Not {
201 result: result.clone(),
202 operand,
203 });
204 result
205 }
206
207 pub fn shl(&mut self, value: Value, shift: Value) -> Value {
208 let result = self.new_temp();
209 self.push_instruction(Instruction::Shl {
210 result: result.clone(),
211 value,
212 shift,
213 });
214 result
215 }
216
217 pub fn shr(&mut self, value: Value, shift: Value) -> Value {
218 let result = self.new_temp();
219 self.push_instruction(Instruction::Shr {
220 result: result.clone(),
221 value,
222 shift,
223 });
224 result
225 }
226
227 pub fn sar(&mut self, value: Value, shift: Value) -> Value {
228 let result = self.new_temp();
229 self.push_instruction(Instruction::Sar {
230 result: result.clone(),
231 value,
232 shift,
233 });
234 result
235 }
236
237 pub fn eq(&mut self, left: Value, right: Value) -> Value {
238 let result = self.new_temp();
239 self.push_instruction(Instruction::Eq {
240 result: result.clone(),
241 left,
242 right,
243 });
244 result
245 }
246
247 pub fn ne(&mut self, left: Value, right: Value) -> Value {
248 let result = self.new_temp();
249 self.push_instruction(Instruction::Ne {
250 result: result.clone(),
251 left,
252 right,
253 });
254 result
255 }
256
257 pub fn lt(&mut self, left: Value, right: Value) -> Value {
258 let result = self.new_temp();
259 self.push_instruction(Instruction::Lt {
260 result: result.clone(),
261 left,
262 right,
263 });
264 result
265 }
266
267 pub fn gt(&mut self, left: Value, right: Value) -> Value {
268 let result = self.new_temp();
269 self.push_instruction(Instruction::Gt {
270 result: result.clone(),
271 left,
272 right,
273 });
274 result
275 }
276
277 pub fn le(&mut self, left: Value, right: Value) -> Value {
278 let result = self.new_temp();
279 self.push_instruction(Instruction::Le {
280 result: result.clone(),
281 left,
282 right,
283 });
284 result
285 }
286
287 pub fn ge(&mut self, left: Value, right: Value) -> Value {
288 let result = self.new_temp();
289 self.push_instruction(Instruction::Ge {
290 result: result.clone(),
291 left,
292 right,
293 });
294 result
295 }
296
297 pub fn select(&mut self, condition: Value, then_val: Value, else_val: Value) -> Value {
298 let result = self.new_temp();
299 self.push_instruction(Instruction::Select {
300 result: result.clone(),
301 condition,
302 then_val,
303 else_val,
304 });
305 result
306 }
307
308 pub fn allocate(&mut self, ty: Type, size: crate::instructions::Size) -> Value {
309 let result = self.new_temp();
310 self.push_instruction(Instruction::Allocate {
311 result: result.clone(),
312 ty,
313 size,
314 });
315 result
316 }
317
318 pub fn storage_load(&mut self, slot: BigUint) -> Value {
319 let result = self.new_temp();
320 let key = StorageKey::Slot(slot);
321 self.push_instruction(Instruction::StorageLoad {
322 result: result.clone(),
323 key,
324 });
325 result
326 }
327
328 pub fn storage_store(&mut self, slot: BigUint, value: Value) {
329 let key = StorageKey::Slot(slot);
330 self.push_instruction(Instruction::StorageStore { key, value });
331 }
332
333 pub fn mapping_load(&mut self, mapping: Value, key: Value) -> Value {
334 let result = self.new_temp();
335 self.push_instruction(Instruction::MappingLoad {
336 result: result.clone(),
337 mapping,
338 key,
339 });
340 result
341 }
342
343 pub fn mapping_store(&mut self, mapping: Value, key: Value, value: Value) {
344 self.push_instruction(Instruction::MappingStore {
345 mapping,
346 key,
347 value,
348 });
349 }
350
351 pub fn array_load(&mut self, array: Value, index: Value) -> Value {
352 let result = self.new_temp();
353 self.push_instruction(Instruction::ArrayLoad {
354 result: result.clone(),
355 array,
356 index,
357 });
358 result
359 }
360
361 pub fn array_store(&mut self, array: Value, index: Value, value: Value) {
362 self.push_instruction(Instruction::ArrayStore {
363 array,
364 index,
365 value,
366 });
367 }
368
369 pub fn array_length(&mut self, array: Value) -> Value {
370 let result = self.new_temp();
371 self.push_instruction(Instruction::ArrayLength {
372 result: result.clone(),
373 array,
374 });
375 result
376 }
377
378 pub fn array_push(&mut self, array: Value, value: Value) {
379 self.push_instruction(Instruction::ArrayPush { array, value });
380 }
381
382 pub fn array_pop(&mut self, array: Value) -> Value {
383 let result = self.new_temp();
384 self.push_instruction(Instruction::ArrayPop {
385 result: result.clone(),
386 array,
387 });
388 result
389 }
390
391 pub fn msg_sender(&mut self) -> Value {
392 let result = self.new_temp();
393 self.push_instruction(Instruction::GetContext {
394 result: result.clone(),
395 var: ContextVariable::MsgSender,
396 });
397 result
398 }
399
400 pub fn msg_value(&mut self) -> Value {
401 let result = self.new_temp();
402 self.push_instruction(Instruction::GetContext {
403 result: result.clone(),
404 var: ContextVariable::MsgValue,
405 });
406 result
407 }
408
409 pub fn block_number(&mut self) -> Value {
410 let result = self.new_temp();
411 self.push_instruction(Instruction::GetContext {
412 result: result.clone(),
413 var: ContextVariable::BlockNumber,
414 });
415 result
416 }
417
418 pub fn block_timestamp(&mut self) -> Value {
419 let result = self.new_temp();
420 self.push_instruction(Instruction::GetContext {
421 result: result.clone(),
422 var: ContextVariable::BlockTimestamp,
423 });
424 result
425 }
426
427 pub fn call_internal(&mut self, name: &str, args: Vec<Value>) -> Value {
428 let result = self.new_temp();
429 self.push_instruction(Instruction::Call {
430 result: result.clone(),
431 target: CallTarget::Internal(name.to_string()),
432 args,
433 value: None,
434 });
435 result
436 }
437
438 pub fn call_external(
439 &mut self,
440 target: Value,
441 selector: Value,
442 args: Vec<Value>,
443 value: Option<Value>,
444 ) -> Value {
445 let result = self.new_temp();
446
447 let mut call_args = vec![selector];
448 call_args.extend(args);
449 self.push_instruction(Instruction::Call {
450 result: result.clone(),
451 target: CallTarget::External(target),
452 args: call_args,
453 value,
454 });
455 result
456 }
457
458 pub fn keccak256(&mut self, data: Value, len: Value) -> Value {
459 let result = self.new_temp();
460 self.push_instruction(Instruction::Keccak256 {
461 result: result.clone(),
462 data,
463 len,
464 });
465 result
466 }
467
468 pub fn sha256(&mut self, data: Value, len: Value) -> Value {
469 let result = self.new_temp();
470 self.push_instruction(Instruction::Sha256 {
471 result: result.clone(),
472 data,
473 len,
474 });
475 result
476 }
477
478 pub fn emit_event(&mut self, event_id: EventId, topics: Vec<Value>, data: Vec<Value>) {
479 self.push_instruction(Instruction::EmitEvent {
480 event: event_id,
481 topics,
482 data,
483 });
484 }
485
486 pub fn cast(&mut self, value: Value, to: Type) -> Value {
487 let result = self.new_temp();
488 self.push_instruction(Instruction::Cast {
489 result: result.clone(),
490 value,
491 to,
492 });
493 result
494 }
495
496 pub fn assert(&mut self, condition: Value, message: &str) {
497 self.push_instruction(Instruction::Assert {
498 condition,
499 message: message.to_string(),
500 });
501 }
502
503 pub fn require(&mut self, condition: Value, message: &str) {
504 self.push_instruction(Instruction::Require {
505 condition,
506 message: message.to_string(),
507 });
508 }
509
510 pub fn assign(&mut self, result: Value, value: Value) {
511 self.push_instruction(Instruction::Assign { result, value });
512 }
513
514 pub fn phi(&mut self, values: Vec<(BlockId, Value)>) -> Value {
515 let result = self.new_temp();
516 self.push_instruction(Instruction::Phi {
517 result: result.clone(),
518 values,
519 });
520 result
521 }
522
523 pub fn jump(&mut self, target: BlockId) -> Result<()> {
524 self.seal_with_terminator(Terminator::Jump(target, Vec::new()))
525 }
526
527 pub fn branch(
528 &mut self,
529 condition: Value,
530 then_block: BlockId,
531 else_block: BlockId,
532 ) -> Result<()> {
533 self.seal_with_terminator(Terminator::Branch {
534 condition,
535 then_block,
536 else_block,
537 then_args: Vec::new(),
538 else_args: Vec::new(),
539 })
540 }
541
542 pub fn return_value(&mut self, value: Value) -> Result<()> {
543 self.seal_with_terminator(Terminator::Return(Some(value)))
544 }
545
546 pub fn return_void(&mut self) -> Result<()> {
547 self.seal_with_terminator(Terminator::Return(None))
548 }
549
550 pub fn revert(&mut self, message: &str) -> Result<()> {
551 self.seal_with_terminator(Terminator::Revert(message.to_string()))
552 }
553
554 pub fn is_sealed(&self) -> bool {
555 self.is_sealed
556 }
557
558 pub fn seal_with_terminator(&mut self, terminator: Terminator) -> Result<()> {
559 if self.is_sealed {
560 return Err(crate::IrError::BuilderError(format!(
561 "Block {} already sealed",
562 self.block_id
563 )));
564 }
565
566 let mut block = BasicBlock::new(self.block_id);
567 block.instructions = self.instructions.clone();
568 block.terminator = terminator;
569
570 block.metadata.instruction_locations = self.instruction_locations.clone();
571
572 self.registry.add_block(self.function_name.clone(), block)?;
573 self.is_sealed = true;
574 Ok(())
575 }
576
577 pub fn new_temp(&mut self) -> Value {
578 let temp_id = self.context.ssa().new_temp();
579 Value::Temp(temp_id)
580 }
581
582 pub fn constant_uint(&self, value: u64, bits: u16) -> Value {
583 Value::Constant(Constant::Uint(BigUint::from(value), bits))
584 }
585
586 pub fn constant_int(&self, value: i64, bits: u16) -> Value {
587 Value::Constant(Constant::Int(BigInt::from(value), bits))
588 }
589
590 pub fn constant_bool(&self, value: bool) -> Value {
591 Value::Constant(Constant::Bool(value))
592 }
593
594 pub fn constant_address(&self, bytes: [u8; 20]) -> Value {
595 Value::Constant(Constant::Address(bytes))
596 }
597}
598
599impl<'a> InstBuilderBase<'a> for BlockBuilder<'a> {
600 fn new_temp(&mut self) -> Value {
601 let temp_id = self.context.ssa().new_temp();
602 Value::Temp(temp_id)
603 }
604
605 fn current_block(&self) -> BlockId {
606 self.block_id
607 }
608
609 fn switch_to_block(&mut self, block: BlockId) {
610 self.block_id = block;
611 self.context.set_current_block(block);
612 }
613}
614
615impl<'a> InstBuilderExt<'a> for BlockBuilder<'a> {
616 fn storage_load(&mut self, slot: BigUint) -> Value {
617 let result = self.new_temp();
618 let key = StorageKey::Slot(slot);
619 self.push_instruction(Instruction::StorageLoad {
620 result: result.clone(),
621 key,
622 });
623 result
624 }
625
626 fn storage_store(&mut self, slot: BigUint, value: Value) {
627 let key = StorageKey::Slot(slot);
628 self.push_instruction(Instruction::StorageStore { key, value });
629 }
630
631 fn storage_load_dynamic(&mut self, slot: Value) -> Value {
632 let result = self.new_temp();
633 let key = StorageKey::Dynamic(slot);
634 self.push_instruction(Instruction::StorageLoad {
635 result: result.clone(),
636 key,
637 });
638 result
639 }
640
641 fn storage_store_dynamic(&mut self, slot: Value, value: Value) {
642 let key = StorageKey::Dynamic(slot);
643 self.push_instruction(Instruction::StorageStore { key, value });
644 }
645
646 fn mapping_load(&mut self, mapping: Value, key: Value) -> Value {
647 let result = self.new_temp();
648 self.push_instruction(Instruction::MappingLoad {
649 result: result.clone(),
650 mapping,
651 key,
652 });
653 result
654 }
655
656 fn mapping_store(&mut self, mapping: Value, key: Value, value: Value) {
657 self.push_instruction(Instruction::MappingStore {
658 mapping,
659 key,
660 value,
661 });
662 }
663
664 fn array_load(&mut self, array: Value, index: Value) -> Value {
665 let result = self.new_temp();
666 self.push_instruction(Instruction::ArrayLoad {
667 result: result.clone(),
668 array,
669 index,
670 });
671 result
672 }
673
674 fn array_store(&mut self, array: Value, index: Value, value: Value) {
675 self.push_instruction(Instruction::ArrayStore {
676 array,
677 index,
678 value,
679 });
680 }
681
682 fn array_length(&mut self, array: Value) -> Value {
683 let result = self.new_temp();
684 self.push_instruction(Instruction::ArrayLength {
685 result: result.clone(),
686 array,
687 });
688 result
689 }
690
691 fn array_push(&mut self, array: Value, value: Value) {
692 self.push_instruction(Instruction::ArrayPush { array, value });
693 }
694
695 fn array_pop(&mut self, array: Value) -> Value {
696 let result = self.new_temp();
697 self.push_instruction(Instruction::ArrayPop {
698 result: result.clone(),
699 array,
700 });
701 result
702 }
703
704 fn msg_sender(&mut self) -> Value {
705 let result = self.new_temp();
706 self.push_instruction(Instruction::GetContext {
707 result: result.clone(),
708 var: ContextVariable::MsgSender,
709 });
710 result
711 }
712
713 fn msg_value(&mut self) -> Value {
714 let result = self.new_temp();
715 self.push_instruction(Instruction::GetContext {
716 result: result.clone(),
717 var: ContextVariable::MsgValue,
718 });
719 result
720 }
721
722 fn msg_data(&mut self) -> Value {
723 let result = self.new_temp();
724 self.push_instruction(Instruction::GetContext {
725 result: result.clone(),
726 var: ContextVariable::MsgData,
727 });
728 result
729 }
730
731 fn block_number(&mut self) -> Value {
732 let result = self.new_temp();
733 self.push_instruction(Instruction::GetContext {
734 result: result.clone(),
735 var: ContextVariable::BlockNumber,
736 });
737 result
738 }
739
740 fn block_timestamp(&mut self) -> Value {
741 let result = self.new_temp();
742 self.push_instruction(Instruction::GetContext {
743 result: result.clone(),
744 var: ContextVariable::BlockTimestamp,
745 });
746 result
747 }
748
749 fn block_difficulty(&mut self) -> Value {
750 let result = self.new_temp();
751 self.push_instruction(Instruction::GetContext {
752 result: result.clone(),
753 var: ContextVariable::BlockDifficulty,
754 });
755 result
756 }
757
758 fn block_gaslimit(&mut self) -> Value {
759 let result = self.new_temp();
760 self.push_instruction(Instruction::GetContext {
761 result: result.clone(),
762 var: ContextVariable::BlockGasLimit,
763 });
764 result
765 }
766
767 fn block_coinbase(&mut self) -> Value {
768 let result = self.new_temp();
769 self.push_instruction(Instruction::GetContext {
770 result: result.clone(),
771 var: ContextVariable::BlockCoinbase,
772 });
773 result
774 }
775
776 fn tx_origin(&mut self) -> Value {
777 let result = self.new_temp();
778 self.push_instruction(Instruction::GetContext {
779 result: result.clone(),
780 var: ContextVariable::TxOrigin,
781 });
782 result
783 }
784
785 fn tx_gasprice(&mut self) -> Value {
786 let result = self.new_temp();
787 self.push_instruction(Instruction::GetContext {
788 result: result.clone(),
789 var: ContextVariable::TxGasPrice,
790 });
791 result
792 }
793
794 fn gas_left(&mut self) -> Value {
795 let result = self.new_temp();
796 self.push_instruction(Instruction::GetContext {
797 result: result.clone(),
798 var: ContextVariable::GasLeft,
799 });
800 result
801 }
802
803 fn msg_sig(&mut self) -> Value {
804 let result = self.new_temp();
805 self.push_instruction(Instruction::GetContext {
806 result: result.clone(),
807 var: ContextVariable::MsgSig,
808 });
809 result
810 }
811
812 fn block_chainid(&mut self) -> Value {
813 let result = self.new_temp();
814 self.push_instruction(Instruction::GetContext {
815 result: result.clone(),
816 var: ContextVariable::ChainId,
817 });
818 result
819 }
820
821 fn block_basefee(&mut self) -> Value {
822 let result = self.new_temp();
823 self.push_instruction(Instruction::GetContext {
824 result: result.clone(),
825 var: ContextVariable::BlockBaseFee,
826 });
827 result
828 }
829
830 fn call_internal(&mut self, name: &str, args: Vec<Value>) -> Value {
831 let result = self.new_temp();
832 self.push_instruction(Instruction::Call {
833 result: result.clone(),
834 target: CallTarget::Internal(name.to_string()),
835 args,
836 value: None,
837 });
838 result
839 }
840
841 fn call_external(
842 &mut self,
843 target: Value,
844 selector: Value,
845 args: Vec<Value>,
846 value: Option<Value>,
847 ) -> Value {
848 self.call_external(target, selector, args, value)
849 }
850
851 fn delegate_call(&mut self, target: Value, selector: Value, args: Vec<Value>) -> Value {
852 let result = self.new_temp();
853 self.push_instruction(Instruction::DelegateCall {
854 result: result.clone(),
855 target,
856 selector,
857 args,
858 });
859 result
860 }
861
862 fn static_call(&mut self, target: Value, selector: Value, args: Vec<Value>) -> Value {
863 let result = self.new_temp();
864 self.push_instruction(Instruction::StaticCall {
865 result: result.clone(),
866 target,
867 selector,
868 args,
869 });
870 result
871 }
872
873 fn emit_event(&mut self, event: EventId, topics: Vec<Value>, data: Vec<Value>) {
874 self.push_instruction(Instruction::EmitEvent {
875 event,
876 topics,
877 data,
878 });
879 }
880
881 fn keccak256(&mut self, data: Value, len: Value) -> Value {
882 let result = self.new_temp();
883 self.push_instruction(Instruction::Keccak256 {
884 result: result.clone(),
885 data,
886 len,
887 });
888 result
889 }
890
891 fn sha256(&mut self, data: Value, len: Value) -> Value {
892 let result = self.new_temp();
893 self.push_instruction(Instruction::Sha256 {
894 result: result.clone(),
895 data,
896 len,
897 });
898 result
899 }
900
901 fn ripemd160(&mut self, data: Value, len: Value) -> Value {
902 let result = self.new_temp();
903 self.push_instruction(Instruction::Ripemd160 {
904 result: result.clone(),
905 data,
906 len,
907 });
908 result
909 }
910
911 fn ecrecover(&mut self, hash: Value, v: Value, r: Value, s: Value) -> Value {
912 let result = self.new_temp();
913 self.push_instruction(Instruction::EcRecover {
914 result: result.clone(),
915 hash,
916 v,
917 r,
918 s,
919 });
920 result
921 }
922
923 fn checked_add(&mut self, left: Value, right: Value, ty: Type) -> Value {
924 let result = self.new_temp();
925 self.push_instruction(Instruction::CheckedAdd {
926 result: result.clone(),
927 left,
928 right,
929 ty,
930 });
931 result
932 }
933
934 fn checked_sub(&mut self, left: Value, right: Value, ty: Type) -> Value {
935 let result = self.new_temp();
936 self.push_instruction(Instruction::CheckedSub {
937 result: result.clone(),
938 left,
939 right,
940 ty,
941 });
942 result
943 }
944
945 fn checked_mul(&mut self, left: Value, right: Value, ty: Type) -> Value {
946 let result = self.new_temp();
947 self.push_instruction(Instruction::CheckedMul {
948 result: result.clone(),
949 left,
950 right,
951 ty,
952 });
953 result
954 }
955
956 fn checked_div(&mut self, left: Value, right: Value, ty: Type) -> Value {
957 let result = self.new_temp();
958 self.push_instruction(Instruction::CheckedDiv {
959 result: result.clone(),
960 left,
961 right,
962 ty,
963 });
964 result
965 }
966
967 fn require(&mut self, condition: Value, message: &str) {
968 self.push_instruction(Instruction::Require {
969 condition,
970 message: message.to_string(),
971 });
972 }
973
974 fn assert(&mut self, condition: Value, message: &str) {
975 self.push_instruction(Instruction::Assert {
976 condition,
977 message: message.to_string(),
978 });
979 }
980
981 fn revert(&mut self, message: &str) {
982 self.push_instruction(Instruction::Revert {
983 message: message.to_string(),
984 });
985 }
986
987 fn memory_alloc(&mut self, size: Value) -> Value {
988 let result = self.new_temp();
989 self.push_instruction(Instruction::MemoryAlloc {
990 result: result.clone(),
991 size,
992 });
993 result
994 }
995
996 fn memory_copy(&mut self, dest: Value, src: Value, size: Value) {
997 self.push_instruction(Instruction::MemoryCopy { dest, src, size });
998 }
999
1000 fn memory_size(&mut self) -> Value {
1001 let result = self.new_temp();
1002 self.push_instruction(Instruction::MemorySize {
1003 result: result.clone(),
1004 });
1005 result
1006 }
1007
1008 fn cast(&mut self, value: Value, to: Type) -> Value {
1009 let result = self.new_temp();
1010 self.push_instruction(Instruction::Cast {
1011 result: result.clone(),
1012 value,
1013 to,
1014 });
1015 result
1016 }
1017
1018 fn zext(&mut self, value: Value, to: Type) -> Value {
1019 let result = self.new_temp();
1020 self.push_instruction(Instruction::ZeroExtend {
1021 result: result.clone(),
1022 value,
1023 to,
1024 });
1025 result
1026 }
1027
1028 fn sext(&mut self, value: Value, to: Type) -> Value {
1029 let result = self.new_temp();
1030 self.push_instruction(Instruction::SignExtend {
1031 result: result.clone(),
1032 value,
1033 to,
1034 });
1035 result
1036 }
1037
1038 fn trunc(&mut self, value: Value, to: Type) -> Value {
1039 let result = self.new_temp();
1040 self.push_instruction(Instruction::Truncate {
1041 result: result.clone(),
1042 value,
1043 to,
1044 });
1045 result
1046 }
1047}
1048
1049impl<'a> InstBuilder<'a> for BlockBuilder<'a> {
1050 fn add(&mut self, left: Value, right: Value, ty: Type) -> Value {
1051 let result = self.new_temp();
1052 self.push_instruction(Instruction::Add {
1053 result: result.clone(),
1054 left,
1055 right,
1056 ty,
1057 });
1058 result
1059 }
1060
1061 fn sub(&mut self, left: Value, right: Value, ty: Type) -> Value {
1062 let result = self.new_temp();
1063 self.push_instruction(Instruction::Sub {
1064 result: result.clone(),
1065 left,
1066 right,
1067 ty,
1068 });
1069 result
1070 }
1071
1072 fn mul(&mut self, left: Value, right: Value, ty: Type) -> Value {
1073 let result = self.new_temp();
1074 self.push_instruction(Instruction::Mul {
1075 result: result.clone(),
1076 left,
1077 right,
1078 ty,
1079 });
1080 result
1081 }
1082
1083 fn div(&mut self, left: Value, right: Value, ty: Type) -> Value {
1084 let result = self.new_temp();
1085 self.push_instruction(Instruction::Div {
1086 result: result.clone(),
1087 left,
1088 right,
1089 ty,
1090 });
1091 result
1092 }
1093
1094 fn mod_(&mut self, left: Value, right: Value, ty: Type) -> Value {
1095 let result = self.new_temp();
1096 self.push_instruction(Instruction::Mod {
1097 result: result.clone(),
1098 left,
1099 right,
1100 ty,
1101 });
1102 result
1103 }
1104
1105 fn pow(&mut self, base: Value, exp: Value) -> Value {
1106 let result = self.new_temp();
1107 self.push_instruction(Instruction::Pow {
1108 result: result.clone(),
1109 base,
1110 exp,
1111 });
1112 result
1113 }
1114
1115 fn and(&mut self, left: Value, right: Value) -> Value {
1116 let result = self.new_temp();
1117 self.push_instruction(Instruction::And {
1118 result: result.clone(),
1119 left,
1120 right,
1121 });
1122 result
1123 }
1124
1125 fn or(&mut self, left: Value, right: Value) -> Value {
1126 let result = self.new_temp();
1127 self.push_instruction(Instruction::Or {
1128 result: result.clone(),
1129 left,
1130 right,
1131 });
1132 result
1133 }
1134
1135 fn xor(&mut self, left: Value, right: Value) -> Value {
1136 let result = self.new_temp();
1137 self.push_instruction(Instruction::Xor {
1138 result: result.clone(),
1139 left,
1140 right,
1141 });
1142 result
1143 }
1144
1145 fn not(&mut self, operand: Value) -> Value {
1146 let result = self.new_temp();
1147 self.push_instruction(Instruction::Not {
1148 result: result.clone(),
1149 operand,
1150 });
1151 result
1152 }
1153
1154 fn shl(&mut self, value: Value, shift: Value) -> Value {
1155 let result = self.new_temp();
1156 self.push_instruction(Instruction::Shl {
1157 result: result.clone(),
1158 value,
1159 shift,
1160 });
1161 result
1162 }
1163
1164 fn shr(&mut self, value: Value, shift: Value) -> Value {
1165 let result = self.new_temp();
1166 self.push_instruction(Instruction::Shr {
1167 result: result.clone(),
1168 value,
1169 shift,
1170 });
1171 result
1172 }
1173
1174 fn sar(&mut self, value: Value, shift: Value) -> Value {
1175 let result = self.new_temp();
1176 self.push_instruction(Instruction::Sar {
1177 result: result.clone(),
1178 value,
1179 shift,
1180 });
1181 result
1182 }
1183
1184 fn eq(&mut self, left: Value, right: Value) -> Value {
1185 let result = self.new_temp();
1186 self.push_instruction(Instruction::Eq {
1187 result: result.clone(),
1188 left,
1189 right,
1190 });
1191 result
1192 }
1193
1194 fn ne(&mut self, left: Value, right: Value) -> Value {
1195 let result = self.new_temp();
1196 self.push_instruction(Instruction::Ne {
1197 result: result.clone(),
1198 left,
1199 right,
1200 });
1201 result
1202 }
1203
1204 fn lt(&mut self, left: Value, right: Value) -> Value {
1205 let result = self.new_temp();
1206 self.push_instruction(Instruction::Lt {
1207 result: result.clone(),
1208 left,
1209 right,
1210 });
1211 result
1212 }
1213
1214 fn gt(&mut self, left: Value, right: Value) -> Value {
1215 let result = self.new_temp();
1216 self.push_instruction(Instruction::Gt {
1217 result: result.clone(),
1218 left,
1219 right,
1220 });
1221 result
1222 }
1223
1224 fn le(&mut self, left: Value, right: Value) -> Value {
1225 let result = self.new_temp();
1226 self.push_instruction(Instruction::Le {
1227 result: result.clone(),
1228 left,
1229 right,
1230 });
1231 result
1232 }
1233
1234 fn ge(&mut self, left: Value, right: Value) -> Value {
1235 let result = self.new_temp();
1236 self.push_instruction(Instruction::Ge {
1237 result: result.clone(),
1238 left,
1239 right,
1240 });
1241 result
1242 }
1243
1244 fn jump(&mut self, target: BlockId, args: Vec<Value>) {
1245 self.push_instruction(Instruction::Jump { target, args });
1246 }
1247
1248 fn branch(
1249 &mut self,
1250 condition: Value,
1251 then_block: BlockId,
1252 else_block: BlockId,
1253 then_args: Vec<Value>,
1254 else_args: Vec<Value>,
1255 ) {
1256 self.push_instruction(Instruction::Branch {
1257 condition,
1258 then_block,
1259 else_block,
1260 then_args,
1261 else_args,
1262 });
1263 }
1264
1265 fn return_value(&mut self, value: Option<Value>) {
1266 self.push_instruction(Instruction::Return { value });
1267 }
1268
1269 fn assign(&mut self, dest: Value, src: Value) {
1270 self.push_instruction(Instruction::Assign {
1271 result: dest,
1272 value: src,
1273 });
1274 }
1275
1276 fn phi(&mut self, values: Vec<(BlockId, Value)>) -> Value {
1277 let result = self.new_temp();
1278 self.push_instruction(Instruction::Phi {
1279 result: result.clone(),
1280 values,
1281 });
1282 result
1283 }
1284}