https://github.com/akkartik/mu/blob/master/apps/mu.subx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204 == data
205
206 Program:
207 0/imm32
208
209 Function-name:
210 0/imm32
211 Function-subx-name:
212 4/imm32
213 Function-inouts:
214 8/imm32
215 Function-outputs:
216 0xc/imm32
217 Function-body:
218 0x10/imm32
219 Function-next:
220 0x14/imm32
221 Function-size:
222 0x18/imm32/24
223
224 Primitive-name:
225 0/imm32
226 Primitive-inouts:
227 8/imm32
228 Primitive-outputs:
229 0xc/imm32
230 Primitive-subx-name:
231 4/imm32
232 Primitive-next:
233 0x14/imm32
234 Primitive-size:
235 0x18/imm32/24
236
237 Stmt-operation:
238 0/imm32
239 Stmt-inouts:
240 4/imm32
241 Stmt-outputs:
242 8/imm32
243 Stmt-next:
244 0xc/imm32
245 Stmt-size:
246 0x10/imm32
247
248 Var-name:
249 0/imm32
250 Var-type:
251 4/imm32
252 Var-block:
253 8/imm32
254 Var-stack-offset:
255 0xc/imm32
256 Var-register-index:
257 0x10/imm32
258 Var-size:
259 0x14/imm32
260
261 == code
262
263 Entry:
264
265 89/<- %ebp 4/r32/esp
266 (new-segment Heap-size Heap)
267
268 {
269
270 81 7/subop/compare *ebp 1/imm32
271 7e/jump-if-lesser-or-equal break/disp8
272
273 (kernel-string-equal? *(ebp+8) "test")
274 3d/compare-eax-and 0/imm32
275 74/jump-if-equal break/disp8
276
277 (run-tests)
278
279 8b/-> *Num-test-failures 3/r32/ebx
280 eb/jump $mu-main:end/disp8
281 }
282
283 (convert-mu Stdin Stdout)
284 (flush Stdout)
285
286 bb/copy-to-ebx 0/imm32
287 $mu-main:end:
288 b8/copy-to-eax 1/imm32/exit
289 cd/syscall 0x80/imm8
290
291 convert-mu:
292
293 55/push-ebp
294 89/<- %ebp 4/r32/esp
295
296 (parse-mu *(ebp+8))
297 (check-mu-types)
298 (emit-subx *(ebp+0xc))
299 $convert-mu:end:
300
301 89/<- %esp 5/r32/ebp
302 5d/pop-to-ebp
303 c3/return
304
305 test-convert-empty-input:
306
307
308 55/push-ebp
309 89/<- %ebp 4/r32/esp
310
311 (clear-stream _test-input-stream)
312 (clear-stream _test-input-buffered-file->buffer)
313 (clear-stream _test-output-stream)
314 (clear-stream _test-output-buffered-file->buffer)
315
316 (convert-mu _test-input-buffered-file _test-output-buffered-file)
317 (flush _test-output-buffered-file)
318 (check-stream-equal _test-output-stream "" "F - test-convert-empty-input")
319
320 89/<- %esp 5/r32/ebp
321 5d/pop-to-ebp
322 c3/return
323
324 test-convert-function-skeleton:
325
326
327
328
329
330
331
332
333
334
335
336
337
338 55/push-ebp
339 89/<- %ebp 4/r32/esp
340
341 (clear-stream _test-input-stream)
342 (clear-stream _test-input-buffered-file->buffer)
343 (clear-stream _test-output-stream)
344 (clear-stream _test-output-buffered-file->buffer)
345
346 (write _test-input-stream "fn foo {\n")
347 (write _test-input-stream "}\n")
348
349 (convert-mu _test-input-buffered-file _test-output-buffered-file)
350 (flush _test-output-buffered-file)
351 +-- 6 lines: #? # dump _test-output-stream --------------------------------------------------------------------------------------------------------------
357
358 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-skeleton/0")
359 (check-next-stream-line-equal _test-output-stream "# . prologue" "F - test-convert-function-skeleton/1")
360 (check-next-stream-line-equal _test-output-stream "55/push-ebp" "F - test-convert-function-skeleton/2")
361 (check-next-stream-line-equal _test-output-stream "89/<- %ebp 4/r32/esp" "F - test-convert-function-skeleton/3")
362 (check-next-stream-line-equal _test-output-stream "# . epilogue" "F - test-convert-function-skeleton/4")
363 (check-next-stream-line-equal _test-output-stream "89/<- %esp 5/r32/ebp" "F - test-convert-function-skeleton/5")
364 (check-next-stream-line-equal _test-output-stream "5d/pop-to-ebp" "F - test-convert-function-skeleton/6")
365 (check-next-stream-line-equal _test-output-stream "c3/return" "F - test-convert-function-skeleton/7")
366
367 89/<- %esp 5/r32/ebp
368 5d/pop-to-ebp
369 c3/return
370
371 test-convert-multiple-function-skeletons:
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395 55/push-ebp
396 89/<- %ebp 4/r32/esp
397
398 (clear-stream _test-input-stream)
399 (clear-stream _test-input-buffered-file->buffer)
400 (clear-stream _test-output-stream)
401 (clear-stream _test-output-buffered-file->buffer)
402
403 (write _test-input-stream "fn foo {\n")
404 (write _test-input-stream "}\n")
405 (write _test-input-stream "fn bar {\n")
406 (write _test-input-stream "}\n")
407
408 (convert-mu _test-input-buffered-file _test-output-buffered-file)
409 (flush _test-output-buffered-file)
410 +-- 6 lines: #? # dump _test-output-stream --------------------------------------------------------------------------------------------------------------
416
417 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-multiple-function-skeletons/0")
418 (check-next-stream-line-equal _test-output-stream "# . prologue" "F - test-convert-multiple-function-skeletons/1")
419 (check-next-stream-line-equal _test-output-stream "55/push-ebp" "F - test-convert-multiple-function-skeletons/2")
420 (check-next-stream-line-equal _test-output-stream "89/<- %ebp 4/r32/esp" "F - test-convert-multiple-function-skeletons/3")
421 (check-next-stream-line-equal _test-output-stream "# . epilogue" "F - test-convert-multiple-function-skeletons/4")
422 (check-next-stream-line-equal _test-output-stream "89/<- %esp 5/r32/ebp" "F - test-convert-multiple-function-skeletons/5")
423 (check-next-stream-line-equal _test-output-stream "5d/pop-to-ebp" "F - test-convert-multiple-function-skeletons/6")
424 (check-next-stream-line-equal _test-output-stream "c3/return" "F - test-convert-multiple-function-skeletons/7")
425
426 (check-next-stream-line-equal _test-output-stream "bar:" "F - test-convert-multiple-function-skeletons/10")
427 (check-next-stream-line-equal _test-output-stream "# . prologue" "F - test-convert-multiple-function-skeletons/11")
428 (check-next-stream-line-equal _test-output-stream "55/push-ebp" "F - test-convert-multiple-function-skeletons/12")
429 (check-next-stream-line-equal _test-output-stream "89/<- %ebp 4/r32/esp" "F - test-convert-multiple-function-skeletons/13")
430 (check-next-stream-line-equal _test-output-stream "# . epilogue" "F - test-convert-multiple-function-skeletons/14")
431 (check-next-stream-line-equal _test-output-stream "89/<- %esp 5/r32/ebp" "F - test-convert-multiple-function-skeletons/15")
432 (check-next-stream-line-equal _test-output-stream "5d/pop-to-ebp" "F - test-convert-multiple-function-skeletons/16")
433 (check-next-stream-line-equal _test-output-stream "c3/return" "F - test-convert-multiple-function-skeletons/17")
434
435 89/<- %esp 5/r32/ebp
436 5d/pop-to-ebp
437 c3/return
438
439 test-convert-function-with-arg:
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458 55/push-ebp
459 89/<- %ebp 4/r32/esp
460
461 (clear-stream _test-input-stream)
462 (clear-stream _test-input-buffered-file->buffer)
463 (clear-stream _test-output-stream)
464 (clear-stream _test-output-buffered-file->buffer)
465
466 (write _test-input-stream "fn foo {\n")
467 (write _test-input-stream "}\n")
468
469 (convert-mu _test-input-buffered-file _test-output-buffered-file)
470 (flush _test-output-buffered-file)
471 +-- 6 lines: #? # dump _test-output-stream --------------------------------------------------------------------------------------------------------------
477
478 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-skeleton/0")
479 (check-next-stream-line-equal _test-output-stream "# . prologue" "F - test-convert-function-skeleton/1")
480 (check-next-stream-line-equal _test-output-stream "55/push-ebp" "F - test-convert-function-skeleton/2")
481 (check-next-stream-line-equal _test-output-stream "89/<- %ebp 4/r32/esp" "F - test-convert-function-skeleton/3")
482 (check-next-stream-line-equal _test-output-stream "# . epilogue" "F - test-convert-function-skeleton/4")
483 (check-next-stream-line-equal _test-output-stream "89/<- %esp 5/r32/ebp" "F - test-convert-function-skeleton/5")
484 (check-next-stream-line-equal _test-output-stream "5d/pop-to-ebp" "F - test-convert-function-skeleton/6")
485 (check-next-stream-line-equal _test-output-stream "c3/return" "F - test-convert-function-skeleton/7")
486
487 89/<- %esp 5/r32/ebp
488 5d/pop-to-ebp
489 c3/return
490
491 parse-mu:
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515 55/push-ebp
516 89/<- %ebp 4/r32/esp
517
518 50/push-eax
519 51/push-ecx
520 52/push-edx
521 57/push-edi
522
523 81 5/subop/subtract %esp 0x200/imm32
524 68/push 0x200/imm32/length
525 68/push 0/imm32/read
526 68/push 0/imm32/write
527 89/<- %ecx 4/r32/esp
528
529 68/push 0/imm32/end
530 68/push 0/imm32/start
531 89/<- %edx 4/r32/esp
532
533 bf/copy-to-edi Program/imm32
534 {
535 $parse-mu:line-loop:
536 (clear-stream %ecx)
537 (read-line-buffered *(ebp+8) %ecx)
538
539 81 7/subop/compare *ecx 0/imm32
540 0f 84/jump-if-equal break/disp32
541 +-- 6 lines: #? # dump line ---------------------------------------------------------------------------------------------------------------------------
547 {
548 $parse-mu:word-loop:
549 (next-word-or-string %ecx %edx)
550
551 (slice-empty? %edx)
552 3d/compare-eax-and 0/imm32
553 0f 85/jump-if-not-equal break/disp32
554
555
556 8b/-> *edx 0/r32/eax
557 8a/copy-byte *eax 0/r32/AL
558 81 4/subop/and %eax 0xff/imm32
559
560 3d/compare-eax-and 0x23/imm32/hash
561 0f 84/jump-if-equal break/disp32
562
563 {
564 (slice-equal? %edx "fn")
565 3d/compare-eax-and 0/imm32
566 0f 84/jump-if-equal break/disp32
567
568 (allocate Heap *Function-size)
569 (populate-mu-function-header %ecx %eax)
570 (populate-mu-function-body *(ebp+8) %eax)
571
572 89/<- *edi 0/r32/eax
573
574 8d/address-> *(eax+0x10) 7/r32/edi
575 e9/jump $parse-mu:word-loop/disp32
576 }
577
578 e9/jump $parse-mu:abort/disp32
579 }
580 e9/jump loop/disp32
581 }
582 $parse-mu:end:
583
584 81 0/subop/add %esp 0x214/imm32
585
586 5f/pop-to-edi
587 5a/pop-to-edx
588 59/pop-to-ecx
589 58/pop-to-eax
590
591 89/<- %esp 5/r32/ebp
592 5d/pop-to-ebp
593 c3/return
594
595 $parse-mu:abort:
596
597 (write-buffered Stderr "unexpected top-level command: ")
598 (write-buffered Stderr %edx)
599 (write-buffered Stderr "\n")
600 (flush Stderr)
601
602 bb/copy-to-ebx 1/imm32
603 b8/copy-to-eax 1/imm32/exit
604 cd/syscall 0x80/imm8
605
606
607
608
609
610
611
612 populate-mu-function-header:
613
614 55/push-ebp
615 89/<- %ebp 4/r32/esp
616
617 50/push-eax
618 51/push-ecx
619 57/push-edi
620
621 8b/-> *(ebp+0xc) 7/r32/edi
622
623 68/push 0/imm32/end
624 68/push 0/imm32/start
625 89/<- %ecx 4/r32/esp
626
627 (next-word *(ebp+8) %ecx)
628 (slice-to-string Heap %ecx)
629 89/<- *edi 0/r32/eax
630
631 (next-word *(ebp+8) %ecx)
632 (slice-equal? %ecx "{")
633 3d/compare-eax-and 0/imm32
634 74/jump-if-equal $populate-mu-function-header:abort/disp8
635
636 {
637
638 (next-word *(ebp+8) %ecx)
639
640 (slice-empty? %ecx)
641 3d/compare-eax-and 0/imm32
642 75/jump-if-not-equal break/disp8
643
644
645 8b/-> *edx 0/r32/eax
646 8a/copy-byte *eax 0/r32/AL
647 81 4/subop/and %eax 0xff/imm32
648
649 3d/compare-eax-and 0x23/imm32/hash
650 74/jump-if-equal break/disp8
651
652 eb/jump $populate-mu-function-header:abort/disp8
653 }
654 $populate-mu-function-header:end:
655
656 81 0/subop/add %esp 8/imm32
657
658 5f/pop-to-edi
659 59/pop-to-ecx
660 58/pop-to-eax
661
662 89/<- %esp 5/r32/ebp
663 5d/pop-to-ebp
664 c3/return
665
666 $populate-mu-function-header:abort:
667
668 (write-buffered Stderr "function header not in form 'fn <name> {' -- '")
669 (rewind-stream *(ebp+8))
670 (write-stream 2 *(ebp+8))
671 (write-buffered Stderr "'\n")
672 (flush Stderr)
673
674 bb/copy-to-ebx 1/imm32
675 b8/copy-to-eax 1/imm32/exit
676 cd/syscall 0x80/imm8
677
678
679
680
681 populate-mu-function-body:
682
683 55/push-ebp
684 89/<- %ebp 4/r32/esp
685
686 50/push-eax
687 51/push-ecx
688 52/push-edx
689 53/push-ebx
690
691 81 5/subop/subtract %esp 0x200/imm32
692 68/push 0x200/imm32/length
693 68/push 0/imm32/read
694 68/push 0/imm32/write
695 89/<- %ecx 4/r32/esp
696
697 68/push 0/imm32/end
698 68/push 0/imm32/start
699 89/<- %edx 4/r32/esp
700
701 bb/copy-to-ebx 1/imm32
702 {
703 $populate-mu-function-body:line-loop:
704
705 81 7/subop/compare %ebx 0/imm32
706 0f 84/jump-if-equal break/disp32
707
708 (clear-stream %ecx)
709 (read-line-buffered *(ebp+8) %ecx)
710
711 81 7/subop/compare *ecx 0/imm32
712 0f 84/jump-if-equal break/disp32
713
714 (next-word %ecx %edx)
715
716 (slice-empty? %ecx)
717 3d/compare-eax-and 0/imm32
718 75/jump-if-not-equal loop/disp8
719
720
721 8b/-> *edx 0/r32/eax
722 8a/copy-byte *eax 0/r32/AL
723 81 4/subop/and %eax 0xff/imm32
724
725 3d/compare-eax-and 0x23/imm32/hash
726 74/jump-if-equal loop/disp8
727 {
728
729 {
730 (slice-equal? %ecx "{")
731 3d/compare-eax-and 0/imm32
732 74/jump-if-equal break/disp8
733 43/increment-ebx
734 eb/jump $curly-found:end/disp8
735 }
736
737 {
738 (slice-equal? %ecx "}")
739 3d/compare-eax-and 0/imm32
740 74/jump-if-equal break/disp8
741 4b/decrement-ebx
742 eb/jump $curly-found:end/disp8
743 }
744
745 eb/jump $populate-mu-function-body:end/disp8
746 }
747
748 $curly-found:end:
749
750 (next-word %ecx %edx)
751
752 (slice-empty? %ecx)
753 3d/compare-eax-and 0/imm32
754 0f 85/jump-if-not-equal loop/disp32
755
756
757 8b/-> *edx 0/r32/eax
758 8a/copy-byte *eax 0/r32/AL
759 81 4/subop/and %eax 0xff/imm32
760
761 3d/compare-eax-and 0x23/imm32/hash
762 0f 84/jump-if-equal loop/disp32
763
764 eb/jump $populate-mu-function-body:abort/disp8
765 }
766 $populate-mu-function-body:end:
767
768 81 0/subop/add %esp 0x214/imm32
769
770 5b/pop-to-ebx
771 5a/pop-to-edx
772 59/pop-to-ecx
773 58/pop-to-eax
774
775 89/<- %esp 5/r32/ebp
776 5d/pop-to-ebp
777 c3/return
778
779 $populate-mu-function-body:abort:
780
781 (write-buffered Stderr "'{' or '}' should be on its own line, but got '")
782 (rewind-stream %ecx)
783 (write-stream 2 %ecx)
784 (write-buffered Stderr "'\n")
785 (flush Stderr)
786
787 bb/copy-to-ebx 1/imm32
788 b8/copy-to-eax 1/imm32/exit
789 cd/syscall 0x80/imm8
790
791
792 check-mu-types:
793
794 55/push-ebp
795 89/<- %ebp 4/r32/esp
796
797 $check-types:end:
798
799 89/<- %esp 5/r32/ebp
800 5d/pop-to-ebp
801 c3/return
802
803 emit-subx:
804
805 55/push-ebp
806 89/<- %ebp 4/r32/esp
807
808 50/push-eax
809 51/push-ecx
810 57/push-edi
811
812 8b/-> *(ebp+8) 7/r32/edi
813
814 8b/-> *Program 1/r32/ecx
815 {
816
817 81 7/subop/compare %ecx 0/imm32
818 0f 84/jump-if-equal break/disp32
819 (emit-subx-function %edi %ecx)
820
821 8b/-> *(ecx+0x10) 1/r32/ecx
822 e9/jump loop/disp32
823 }
824 $emit-subx:end:
825
826 5f/pop-to-edi
827 59/pop-to-ecx
828 58/pop-to-eax
829
830 89/<- %esp 5/r32/ebp
831 5d/pop-to-ebp
832 c3/return
833
834
835
836
837
838
839
840 emit-subx-function:
841
842 55/push-ebp
843 89/<- %ebp 4/r32/esp
844
845 50/push-eax
846 51/push-ecx
847 57/push-edi
848
849 8b/-> *(ebp+8) 7/r32/edi
850
851 8b/-> *(ebp+0xc) 1/r32/ecx
852
853 (write-buffered %edi *ecx)
854 (write-buffered %edi ":\n")
855 (emit-subx-prologue %edi)
856 (emit-subx-block %edi *(ecx+0x10))
857 (emit-subx-epilogue %edi)
858 $emit-subx-function:end:
859
860 5f/pop-to-edi
861 59/pop-to-ecx
862 58/pop-to-eax
863
864 89/<- %esp 5/r32/ebp
865 5d/pop-to-ebp
866 c3/return
867
868 emit-subx-block:
869
870 55/push-ebp
871 89/<- %ebp 4/r32/esp
872
873 $emit-subx-block:end:
874
875 89/<- %esp 5/r32/ebp
876 5d/pop-to-ebp
877 c3/return
878
879 emit-subx-statement:
880
881 55/push-ebp
882 89/<- %ebp 4/r32/esp
883
884 50/push-eax
885 51/push-ecx
886
887 {
888 (find-matching-function *(ebp+0x14) *(ebp+0xc))
889 3d/compare-eax-and 0/imm32
890 74/jump-if-equal break/disp8
891 (emit-subx-primitive *(ebp+8) *(ebp+0xc) *(ebp+0x10) %eax)
892 e9/jump $emit-subx-statement:end/disp32
893 }
894
895 {
896 (find-matching-function *(ebp+0x18) *(ebp+0xc))
897 3d/compare-eax-and 0/imm32
898 74/jump-if-equal break/disp8
899 (emit-subx-call *(ebp+8) *(ebp+0xc) *(ebp+0x10) %eax)
900 e9/jump $emit-subx-statement:end/disp32
901 }
902
903 e9/jump $emit-subx-statement:abort/disp32
904 $emit-subx-statement:end:
905
906 59/pop-to-ecx
907 58/pop-to-eax
908
909 89/<- %esp 5/r32/ebp
910 5d/pop-to-ebp
911 c3/return
912
913 $emit-subx-statement:abort:
914
915 (write-buffered Stderr "couldn't translate '")
916
917 (write-buffered Stderr "'\n")
918 (flush Stderr)
919
920 bb/copy-to-ebx 1/imm32
921 b8/copy-to-eax 1/imm32/exit
922 cd/syscall 0x80/imm8
923
924
925 emit-subx-primitive:
926
927 55/push-ebp
928 89/<- %ebp 4/r32/esp
929
930 50/push-eax
931 51/push-ecx
932
933 8b/-> *(ebp+0x14) 1/r32/ecx
934 (write-buffered *(ebp+8) *(ecx+4))
935
936
937 8b/-> *(ebp+0xc) 1/r32/ecx
938 8b/-> *(ecx+4) 1/r32/ecx
939 {
940
941 81 7/subop/compare %ecx 0/imm32
942 74/jump-if-equal break/disp8
943
944 (emit-subx-call-operand *(ebp+8) *ecx)
945
946 8b/-> *(ecx+4) 1/r32/ecx
947 }
948 $emit-subx-primitive:end:
949
950 59/pop-to-ecx
951 58/pop-to-eax
952
953 89/<- %esp 5/r32/ebp
954 5d/pop-to-ebp
955 c3/return
956
957 emit-subx-call:
958
959 55/push-ebp
960 89/<- %ebp 4/r32/esp
961
962 50/push-eax
963 51/push-ecx
964
965 (write-buffered *(ebp+8) "(")
966
967 8b/-> *(ebp+0x14) 1/r32/ecx
968 (write-buffered *(ebp+8) *(ecx+4))
969
970
971 8b/-> *(ebp+0xc) 1/r32/ecx
972 8b/-> *(ecx+4) 1/r32/ecx
973 {
974
975 81 7/subop/compare %ecx 0/imm32
976 74/jump-if-equal break/disp8
977
978 (emit-subx-call-operand *(ebp+8) *ecx)
979
980 8b/-> *(ecx+4) 1/r32/ecx
981 }
982
983 (write-buffered *(ebp+8) ")")
984 $emit-subx-call:end:
985
986 59/pop-to-ecx
987 58/pop-to-eax
988
989 89/<- %esp 5/r32/ebp
990 5d/pop-to-ebp
991 c3/return
992
993 emit-subx-call-operand:
994
995 55/push-ebp
996 89/<- %ebp 4/r32/esp
997
998 50/push-eax
999
1000 (write-buffered *(ebp+8) Space)
1001 (write-buffered *(ebp+8) "*(ebp+")
1002 8b/-> *(ebp+0xc) 0/r32/eax
1003 (print-int32-buffered *(ebp+8) *(eax+0xc))
1004 (write-buffered *(ebp+8) ")")
1005 $emit-subx-call-operand:end:
1006
1007 58/pop-to-eax
1008
1009 89/<- %esp 5/r32/ebp
1010 5d/pop-to-ebp
1011 c3/return
1012
1013 find-matching-function:
1014
1015 55/push-ebp
1016 89/<- %ebp 4/r32/esp
1017
1018 51/push-ecx
1019
1020 8b/-> *(ebp+8) 1/r32/ecx
1021 {
1022
1023 81 7/subop/compare %ecx 0/imm32
1024 74/jump-if-equal break/disp8
1025
1026 {
1027 (mu-stmt-matches-function? *(ebp+0xc) %ecx)
1028 3d/compare-eax-and 0/imm32
1029 74/jump-if-equal break/disp8
1030 89/<- %eax 1/r32/ecx
1031 eb/jump $find-matching-function:end/disp8
1032 }
1033
1034 8b/-> *(ecx+0x10) 1/r32/ecx
1035 eb/jump loop/disp8
1036 }
1037
1038 b8/copy-to-eax 0/imm32
1039 $find-matching-function:end:
1040
1041 59/pop-to-ecx
1042
1043 89/<- %esp 5/r32/ebp
1044 5d/pop-to-ebp
1045 c3/return
1046
1047 mu-stmt-matches-function?:
1048
1049 55/push-ebp
1050 89/<- %ebp 4/r32/esp
1051
1052 51/push-ecx
1053
1054 8b/-> *(ebp+8) 1/r32/ecx
1055 8b/-> *(ebp+0xc) 0/r32/eax
1056 (string-equal? *ecx *eax)
1057 $mu-stmt-matches-function?:end:
1058
1059 59/pop-to-ecx
1060
1061 89/<- %esp 5/r32/ebp
1062 5d/pop-to-ebp
1063 c3/return
1064
1065 test-emit-subx-statement-primitive:
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084 55/push-ebp
1085 89/<- %ebp 4/r32/esp
1086
1087 (clear-stream _test-output-stream)
1088 (clear-stream _test-output-buffered-file->buffer)
1089
1090 68/push 0/imm32/no-register
1091 68/push -8/imm32/stack-offset
1092 68/push 1/imm32/block-depth
1093 68/push 1/imm32/type-int
1094 68/push "foo"/imm32
1095 89/<- %ecx 4/r32/esp
1096
1097 51/push-ecx/var-foo
1098 68/push 1/imm32/data-length
1099 68/push 1/imm32/top
1100 89/<- %edx 4/r32/esp
1101
1102 68/push 0/imm32/next
1103 51/push-ecx/var-foo
1104 89/<- %esi 4/r32/esp
1105
1106 68/push 0/imm32/next
1107 68/push 0/imm32/outputs
1108 56/push-esi/operands
1109 68/push "increment"/imm32/operation
1110 89/<- %esi 4/r32/esp
1111
1112 68/push 0/imm32/next
1113 68/push 0/imm32/body
1114 68/push 0/imm32/outputs
1115 51/push-ecx/inouts
1116 68/push "ff 0/subop/increment"/imm32/subx-name
1117 68/push "increment"/imm32/name
1118 89/<- %ebx 4/r32/esp
1119
1120 (emit-subx-statement _test-output-buffered-file %esi %edx %ebx 0)
1121 (flush _test-output-buffered-file)
1122 +-- 6 lines: #? # dump _test-output-stream --------------------------------------------------------------------------------------------------------------
1128
1129 (check-next-stream-line-equal _test-output-stream "ff 0/subop/increment *(ebp+0xfffffff8)" "F - test-emit-subx-statement-primitive/0")
1130
1131 81 0/subop/add %esp 0x48/imm32
1132
1133 89/<- %esp 5/r32/ebp
1134 5d/pop-to-ebp
1135 c3/return
1136
1137 test-emit-subx-statement-function-call:
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158 55/push-ebp
1159 89/<- %ebp 4/r32/esp
1160
1161 (clear-stream _test-output-stream)
1162 (clear-stream _test-output-buffered-file->buffer)
1163
1164 68/push 0/imm32/no-register
1165 68/push -8/imm32/stack-offset
1166 68/push 0/imm32/block-depth
1167 68/push 1/imm32/type-int
1168 68/push "foo"/imm32
1169 89/<- %ecx 4/r32/esp
1170
1171 51/push-ecx/var-foo
1172 68/push 1/imm32/data-length
1173 68/push 1/imm32/top
1174 89/<- %edx 4/r32/esp
1175
1176 68/push 0/imm32/next
1177 51/push-ecx/var-foo
1178 89/<- %esi 4/r32/esp
1179
1180 68/push 0/imm32/next
1181 68/push 0/imm32/outputs
1182 56/push-esi/inouts
1183 68/push "f"/imm32/operation
1184 89/<- %esi 4/r32/esp
1185
1186 68/push 0/imm32/next
1187 68/push 0/imm32/body
1188 68/push 0/imm32/outputs
1189 51/push-ecx/inouts
1190 68/push "f2"/imm32/subx-name
1191 68/push "f"/imm32/name
1192 89/<- %ebx 4/r32/esp
1193
1194 (emit-subx-statement _test-output-buffered-file %esi %edx 0 %ebx)
1195 (flush _test-output-buffered-file)
1196 +-- 6 lines: #? # dump _test-output-stream --------------------------------------------------------------------------------------------------------------
1202
1203 (check-next-stream-line-equal _test-output-stream "(f2 *(ebp+0xfffffff8))" "F - test-emit-subx-statement-function-call/0")
1204
1205 81 0/subop/add %esp 0x3c/imm32
1206
1207 89/<- %esp 5/r32/ebp
1208 5d/pop-to-ebp
1209 c3/return
1210
1211 emit-subx-prologue:
1212
1213 55/push-ebp
1214 89/<- %ebp 4/r32/esp
1215
1216 (write-buffered *(ebp+8) "# . prologue\n")
1217 (write-buffered *(ebp+8) "55/push-ebp\n")
1218 (write-buffered *(ebp+8) "89/<- %ebp 4/r32/esp\n")
1219 $emit-subx-prologue:end:
1220
1221 89/<- %esp 5/r32/ebp
1222 5d/pop-to-ebp
1223 c3/return
1224
1225 emit-subx-epilogue:
1226
1227 55/push-ebp
1228 89/<- %ebp 4/r32/esp
1229
1230 (write-buffered *(ebp+8) "# . epilogue\n")
1231 (write-buffered *(ebp+8) "89/<- %esp 5/r32/ebp\n")
1232 (write-buffered *(ebp+8) "5d/pop-to-ebp\n")
1233 (write-buffered *(ebp+8) "c3/return\n")
1234 $emit-subx-epilogue:end:
1235
1236 89/<- %esp 5/r32/ebp
1237 5d/pop-to-ebp
1238 c3/return