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